When to Use
| Use Case | Types to Import |
|---|---|
| Fetching page data from Kirby's API | KirbyApiResponse, KirbyBlock, KirbyLayout |
| Building KQL queries with type safety | KirbyQueryRequest, KirbyQueryResponse |
| Developing Panel plugins (Vue components, custom fields) | Panel, PanelApi |
| Creating Writer extensions (rich text editor) | WriterMarkExtension, WriterNodeExtension |
Setup
# pnpm
pnpm add -D kirby-types
# npm
npm i -D kirby-types
# yarn
yarn add -D kirby-types
Quick Start
Typing KQL Responses
import type { KirbyQueryRequest, KirbyQueryResponse } from "kirby-types";
// Define your query with full type safety
const request: KirbyQueryRequest = {
query: "site",
select: {
title: true,
children: {
query: "site.children",
select: ["id", "title", "isListed"],
},
},
};
// Type the response
interface SiteData {
title: string;
children: { id: string; title: string; isListed: boolean }[];
}
type Response = KirbyQueryResponse<SiteData>;
Typing Blocks with Content
import type { KirbyBlock } from "kirby-types";
// Default block types are fully typed
const textBlock: KirbyBlock<"text"> = {
id: "abc123",
type: "text",
isHidden: false,
content: { text: "<p>Hello world</p>" },
};
// Custom blocks with your own content structure
interface HeroContent {
title: string;
image: string;
cta: string;
}
const heroBlock: KirbyBlock<"hero", HeroContent> = {
id: "def456",
type: "hero",
isHidden: false,
content: {
title: "Welcome",
image: "hero.jpg",
cta: "Learn more",
},
};
Typing Layouts
import type { KirbyBlock, KirbyLayout } from "kirby-types";
const layout: KirbyLayout = {
id: "layout-1",
attrs: { class: "highlight" },
columns: [
{ id: "col-1", width: "1/3", blocks: [] },
{ id: "col-2", width: "2/3", blocks: [] },
],
};
Common Patterns
Pattern 1: Full Page Response with Blocks and Layouts
import type { KirbyBlock, KirbyLayout, PanelModelData } from "kirby-types";
// Define custom block types alongside defaults
interface CallToActionContent {
text: string;
url: string;
style: "primary" | "secondary";
}
type CustomBlock =
| KirbyBlock<"text">
| KirbyBlock<"heading">
| KirbyBlock<"image">
| KirbyBlock<"cta", CallToActionContent>;
interface BlogPostContent {
date: string;
author: string;
blocks: CustomBlock[];
layout: KirbyLayout[];
}
type BlogPostPage = PanelModelData<BlogPostContent>;
Pattern 2: KQL Queries with Pagination
import type { KirbyQueryRequest, KirbyQueryResponse } from "kirby-types";
// Define request
const request: KirbyQueryRequest = {
query: 'page("blog").children.listed',
select: {
title: "page.title",
date: "page.date.toDate",
excerpt: "page.text.toBlocks.excerpt(200)",
},
pagination: { limit: 10, page: 1 },
};
// Type the response data
interface BlogPostSummary {
title: string;
date: string;
excerpt: string;
}
// With pagination (second generic = true)
type PaginatedResponse = KirbyQueryResponse<BlogPostSummary[], true>;
// Response shape:
// {
// code: 200,
// status: "ok",
// result: {
// data: BlogPostSummary[],
// pagination: { page, pages, offset, limit, total }
// }
// }
Panel Types
The Panel types track Kirby's own sources: every
window.panelmember is verified against the PHP response shape (toArray()/props()), Kirby 6's official TypeScript Panel client, and the Kirby 5 JavaScript client – PHP wins where they disagree. Members added after Kirby 4 carry a git-verified@sincetag, so your editor flags anything newer than the Kirby version you target.
For Panel plugin development, type the global window.panel object:
import type { Panel } from "kirby-types";
declare global {
interface Window {
panel: Panel;
}
}
Common Panel operations:
// Notifications
window.panel.notification.success("Changes saved");
window.panel.notification.error("Something went wrong");
// Theme
window.panel.theme.set("dark");
// Navigation
await window.panel.view.open("/pages/blog");
await window.panel.dialog.open("/dialogs/pages/create");
// API calls
const page = await window.panel.api.pages.get("blog");
await window.panel.api.pages.update("blog", { title: "New Title" });
// Content state
const currentContent = panel.content.version("changes");
Advanced: Writer Extensions
For ProseMirror-based Writer extensions (requires optional peer dependencies):
import type { WriterMarkExtension } from "kirby-types";
const highlight: WriterMarkExtension = {
button: {
icon: "highlight",
label: "Highlight",
},
commands({ type, utils }) {
return () => utils.toggleMark(type);
},
inputRules({ type, utils }) {
return [utils.markInputRule(/\*\*([^*]+)\*\*$/, type)];
},
schema: {
parseDOM: [{ tag: "mark" }],
toDOM: () => ["mark", 0],
},
};
Required peer dependencies for Writer types
pnpm add -D prosemirror-commands prosemirror-inputrules prosemirror-model prosemirror-schema-list prosemirror-state prosemirror-view
API Reference
Content Types (Most Used)
| Type | Description |
|---|---|
KirbyApiResponse<T> |
Standard API response wrapper |
KirbyBlock<T, U> |
Block with type and content |
KirbyLayout |
Layout row with columns |
KirbyLayoutColumn |
Column with width and blocks |
KirbyDefaultBlocks |
Map of default block content types |
KirbyDefaultBlockType |
Union of default block type names |
KQL Types
| Type | Description |
|---|---|
KirbyQueryRequest |
KQL request with pagination |
KirbyQueryResponse<T, P> |
KQL response with optional pagination |
KirbyQuerySchema |
KQL query schema structure |
KirbyQuery<M> |
Valid KQL query string |
ParseKirbyQuery<T> |
Parse query string to structured type |
Panel Types
| Type | Description |
|---|---|
Panel |
Main Panel interface |
PanelApi |
API client methods |
PanelState |
Base state interface |
PanelFeature |
Feature with loading states |
PanelModal |
Modal (dialog/drawer) interface |
PanelHelpers |
Utility functions |
Blueprint Types
| Type | Description |
|---|---|
KirbyFieldProps |
Base field props from Field->toArray() |
KirbyFieldsetProps |
Fieldset from Fieldset->toArray() |
KirbyBlocksFieldProps |
Blocks field props with fieldsets |
KirbyStructureFieldProps |
Structure field props with nested fields |
KirbyLayoutFieldProps |
Layout field props with settings |
KirbyAnyFieldProps |
Union of all field prop types |
Writer Types
| Type | Description |
|---|---|
WriterEditor |
Main editor instance |
WriterMarkExtension |
Mark extension interface |
WriterNodeExtension |
Node extension interface |
WriterUtils |
ProseMirror commands and utilities |
View all Blueprint field types
| Type | Description |
|---|---|
KirbyTextFieldProps |
Text field props |
KirbyTextareaFieldProps |
Textarea field props |
KirbyNumberFieldProps |
Number field props |
KirbyDateFieldProps |
Date and time field props |
KirbyFilesFieldProps |
Files/pages/users picker props |
KirbyOptionsFieldProps |
Select/radio/checkboxes/toggles |
KirbyToggleFieldProps |
Toggle (boolean) field props |
KirbyColorFieldProps |
Color picker field props |
KirbyRangeFieldProps |
Range slider field props |
KirbyTagsFieldProps |
Tags field props |
KirbyLinkFieldProps |
Link field props |
KirbyObjectFieldProps |
Object field props |
KirbyWriterFieldProps |
Writer (rich text) field props |
Optional Dependencies
Vue is an optional peer dependency for Panel types:
pnpm add -D vue@^2.7.0
dayjs is another optional peer dependency – it powers the $library.dayjs types, including Kirby's plugin extensions (toISO, interpret, pattern, …):
pnpm add -D dayjs
License
MIT License 2022-PRESENT Johann Schopplich