API Reference
Reference for the primary public exports from @glokki-cms/sdk and @glokki-cms/react.
For step-by-step integration instructions, see the Integration Guide. For block development patterns, see the Block Development Guide.
@glokki-cms/sdk
defineBlock()
The primary SDK API for block registration. Declares a block with metadata, a Zod schema, and a React component. Auto-serializes the Zod schema into FieldDescriptor[] so the CMS never touches Zod directly.
import { defineBlock } from "@glokki-cms/sdk"
Signature
function defineBlock<TSchema, TComponent>(
config: DefineBlockConfig<TSchema, TComponent>
): BlockRegistryEntry<InferOutput<TSchema>, TComponent>
DefineBlockConfig
| Property | Type | Required | Description |
|---|---|---|---|
type | string | Yes | Unique block type key (e.g., "hero", "rich-text") |
label | string | Yes | Human-readable display name |
category | BlockCategory (a string) | Yes | Category key this block is grouped under. Any key without whitespace, 1–64 characters. Must appear in the registry's categories option when one is declared; otherwise use one of the CMS built-ins (content, layout, media, interactive, list) |
icon | string | Yes | Lucide icon name for the component library browser |
description | string | No | Short description shown in the component library browser |
defaultProps | InferOutput<TSchema> | Yes | Default props when adding a new instance (type-safe, inferred from schema) |
propsSchema | TSchema | Yes | Zod z.object() schema describing the block's props |
viewportDefaults | ViewportOverrides<TProps> | No | Per-viewport prop defaults ({ tablet?: Partial<TProps>, mobile?: Partial<TProps> }) |
slots | SlotDefinition[] | (props) => SlotDefinition[] | No | Slot definitions for blocks that can contain child blocks. Static array or a function that derives slots from current props |
component | TComponent | Yes | React component that renders the block |
Returns
A BlockRegistryEntry with pre-serialized fields: FieldDescriptor[], ready for createBlockRegistry().
Example
import { z } from "zod"
import { defineBlock } from "@glokki-cms/sdk"
import { HeroComponent } from "./hero"
const heroSchema = z.object({
heading: z.string().min(1).max(120).describe("Heading"),
subheading: z.string().max(240).optional().describe("Subheading"),
alignment: z.enum(["left", "center", "right"]).default("center"),
})
export const HeroBlock = defineBlock({
type: "hero",
label: "Hero",
category: "content",
icon: "Sparkles",
defaultProps: {
heading: "Hello World",
alignment: "center",
},
propsSchema: heroSchema,
component: HeroComponent,
})
Errors
Throws if propsSchema is not a z.object() schema (e.g., z.record(), z.string()). Only z.object() schemas can be serialized into field descriptors.
createBlockRegistry()
Creates a typed block registry from an array of defineBlock() results. The registry provides component lookup, wire-safe serialized definitions for the iframe handshake, and type introspection.
import { createBlockRegistry } from "@glokki-cms/sdk"
Signature
function createBlockRegistry(
entries: BlockRegistryEntry[],
options?: BlockRegistryOptions
): BlockRegistry
BlockRegistryOptions
| Property | Type | Required | Description |
|---|---|---|---|
categories | BlockCategoryDefinition[] | No | The tenant's own ordered { key, label } block categories. Omit it to keep the CMS's built-in five (content, layout, media, interactive, list) |
A declared list replaces the CMS's built-in categories — it never merges
with them — and the block picker renders the categories in the array's order.
Keys and labels must be non-empty and at most 64 characters, and a key may not
contain whitespace. Every block's category must appear in the list;
createBlockRegistry throws at build time otherwise.
BlockRegistry
| Method | Returns | Description |
|---|---|---|
getComponent(type) | unknown | undefined | Look up the rendering component for a block type |
getSerializedDefinitions() | SerializedBlockDefinition[] | Wire-safe definitions for the iframe handshake (no Zod, no React) |
getTypes() | string[] | All registered block type strings (e.g., ["hero", "cta"]) |
getCategories() | readonly BlockCategoryDefinition[] | undefined | The categories declared via options.categories, in declaration order, or undefined when none were declared. Sent to the CMS on the iframe handshake |
resolveSlots(type, props) | SlotDefinition[] | undefined | Resolve slot definitions for a block given its current props. Evaluates dynamic slot functions |
hasDynamicSlots(type) | boolean | Returns true if a block's slots are defined as a function of props |
Example
import { createBlockRegistry, defineBlock } from "@glokki-cms/sdk"
const HeroBlock = defineBlock({ type: "hero" /* ... */ })
const CtaBlock = defineBlock({ type: "cta" /* ... */ })
const registry = createBlockRegistry([HeroBlock, CtaBlock], {
categories: [
{ key: "content", label: "Content" },
{ key: "interactive", label: "Interactive" },
],
})
registry.getTypes() // ["hero", "cta"]
registry.getComponent("hero") // HeroComponent
registry.getSerializedDefinitions() // SerializedBlockDefinition[]
registry.getCategories() // the two declared categories, in order
Errors
Throws if duplicate block types are detected in the entries array, and — when
categories is declared — if the list is empty, holds a duplicate key, has an
invalid key or label, or omits a category that one of the blocks names.
createClient()
Creates a typed client for the CMS Delivery API. Supports fetching pages, navigation, redirects, A/B experiment resolution, and collections.
import { createClient } from "@glokki-cms/sdk"
Signature
function createClient(options: ClientOptions): CMSClient
ClientOptions
| Property | Type | Required | Description |
|---|---|---|---|
baseUrl | string | Yes | Base URL of the CMS API (e.g., "http://localhost:3000") |
apiKey | string | No | API key for authentication (sent as Authorization: Bearer header) |
tenantSlug | string | No | Tenant slug (sent as X-Tenant-Slug header) |
preview | boolean | No | Enable preview mode to fetch draft content |
previewToken | string | No | Preview token for draft content access |
fetchInit | RequestInit | No | Default RequestInit merged into every fetch call. Controls framework-level caching (see below) |
The fetchInit option lets you control Next.js caching behavior:
// Always fresh (disables ISR/SSG)
createClient({ baseUrl, fetchInit: { cache: "no-store" } })
// On-demand revalidation via tags
createClient({ baseUrl, fetchInit: { next: { tags: ["cms"] } } })
// ISR with 60-second TTL
createClient({ baseUrl, fetchInit: { next: { revalidate: 60 } } })
CMSClient
The client object returned by createClient() exposes these namespaces:
client.pages
| Method | Returns | Description |
|---|---|---|
getBySlug(slug, opts?) | Promise<DeliveryPage | null> | Fetch a published page by slug. Returns null for 404. Supports locale and visitorId options |
list(opts?) | Promise<{ data, meta }> | List published pages. Returns DeliveryPageListItem[] with PaginationMeta |
client.navigation
| Method | Returns | Description |
|---|---|---|
get(opts?) | Promise<NavigationItem[]> | Fetch navigation items (slug, title, locale) for published pages |
client.redirects
| Method | Returns | Description |
|---|---|---|
list() | Promise<DeliveryRedirect[]> | Fetch all active redirect rules |
client.experiments
| Method | Returns | Description |
|---|---|---|
resolveVariant(experimentId, visitorId, opts?) | Promise<VariantResolution | null> | Resolve which A/B variant a visitor should see. Deterministic assignment. Pass { recordImpression: true } to track atomically |
recordImpression(experimentId, visitorId) | Promise<void> | Record an impression. Do NOT use after pages.getBySlug() (it already records impressions) |
recordConversion(experimentId, visitorId) | Promise<void> | Record a conversion event for an experiment |
client.collections
| Method | Returns | Description |
|---|---|---|
list(opts?) | Promise<{ data, meta }> | List all collections for the tenant |
getBySlug(slug) | Promise<DeliveryCollection | null> | Fetch a collection by slug. Returns null for 404 |
listEntries(slug, opts?) | Promise<{ entries, pagination }> | List published entries. Supports pagination, sorting, tag filtering, locale filtering, and dynamic field filters |
ListCollectionEntriesOptions
| Property | Type | Description |
|---|---|---|
page | number | Page number (default: 1) |
limit | number | Entries per page (max: 100) |
sortBy | string | Sort field: "published_at", "created_at", "updated_at", "title", or a sortable custom field key |
sortDirection | "asc" | "desc" | Sort direction |
locale | string | Filter by locale |
tag | string | Filter by tag slug |
fields | Record<string, string> | Dynamic field filters (e.g., { author: "John" }) |
Field filters. fields (or ?field.<key>=<value> on the raw endpoint) filters on custom fields that are sortable, shown in the list, or filterable. Text fields match partially, select/boolean exactly, and date/number fields accept <key>_gte / <key>_lte. Data model reference fields accept a record UUID or a record key ({ topics: "seo" }); a multi reference (dataModelRefs) matches entries that contain the record. A key that matches no record returns an empty list rather than ignoring the filter. Repeating a parameter on the raw endpoint (?field.topics=seo&field.topics=performance) requires all of them.
Example
const cms = createClient({
baseUrl: process.env.CMS_BASE_URL!,
tenantSlug: process.env.CMS_TENANT!,
apiKey: process.env.CMS_API_KEY!,
fetchInit: { next: { tags: ["cms-pages"] } },
})
// Fetch a page
const page = await cms.pages.getBySlug("about")
// List pages
const { data: pages, meta } = await cms.pages.list({ limit: 10 })
// Collections
const { entries } = await cms.collections.listEntries("blog", {
page: 1,
limit: 10,
sortBy: "published_at",
sortDirection: "desc",
tag: "featured",
})
CMSError
Error class thrown when the Delivery API returns an error response.
import { CMSError } from "@glokki-cms/sdk"
Properties
| Property | Type | Description |
|---|---|---|
code | string | Machine-readable error code (e.g., "NOT_FOUND", "UNAUTHORIZED") |
message | string | Human-readable error message |
status | number | HTTP status code |
Example
try {
// Note: pages.getBySlug() returns null for 404, not an error.
// CMSError is thrown for non-404 errors like auth failures.
const nav = await cms.navigation.get()
} catch (error) {
if (error instanceof CMSError) {
console.log(error.code) // "UNAUTHORIZED"
console.log(error.status) // 401
}
}
serializeBlockSchema()
Low-level utility that converts a Zod z.object() schema into FieldDescriptor[]. Used internally by defineBlock() — you typically don't need to call this directly.
import { serializeBlockSchema } from "@glokki-cms/sdk"
Signature
function serializeBlockSchema(schema: ZodObjectSchema): FieldDescriptor[]
@glokki-cms/react
VisualEditorProvider
Context provider that manages visual editor state. In normal mode, renders the fallbackTree with zero overhead. In editor mode (when loaded inside the CMS iframe), initiates a postMessage handshake with the CMS and syncs the component tree, selection, and viewport in real-time.
import { VisualEditorProvider } from "@glokki-cms/react"
Props (VisualEditorProviderProps)
| Prop | Type | Required | Description |
|---|---|---|---|
registry | ComponentRegistry | Yes | Component registry mapping block types to React components. Should be a stable reference (module-level or memoized) |
blockRegistry | BlockRegistry | No | Typed block registry from createBlockRegistry(). Enables v2 handshake with full block definitions and dynamic slot updates |
layoutRegistry | LayoutRegistry | Yes | Layout registry from createLayoutRegistry(). Serialized into the handshake and used to render header/footer chrome around the block tree |
fallbackTree | ComponentNode[] | No | Component tree for non-editor mode. Typically from the Delivery API (default: []) |
pageSlug | string | No | Page slug sent in the handshake (e.g., "/about") |
tenantSlug | string | No | Tenant slug this app serves (e.g., process.env.NEXT_PUBLIC_CMS_TENANT). Enables the cross-tenant guard: on a mismatch with the editing session's tenant the CMS shows a connection error and the provider withholds its ready reply, so no draft content is exchanged. Omit to skip the check |
children | ReactNode | Yes | Child components |
Behavior
- Normal mode: Uses
fallbackTreeas the component tree. No postMessage bridge overhead. - Editor mode (detected via
?_editor=1&_editorOrigin=...query params): Initiates handshake with the CMS, then receivestree:update,block:select,viewport:change,block:props-update,block:scroll-into-view, andtoken:refreshmessages.
Example
<VisualEditorProvider
registry={registry}
blockRegistry={blockRegistry}
layoutRegistry={layoutRegistry}
fallbackTree={page.componentTree}
pageSlug="/about"
tenantSlug={process.env.NEXT_PUBLIC_CMS_TENANT}
>
<CMSPageEditor />
</VisualEditorProvider>
useVisualEditor()
Hook that reads the visual editor context. Must be called within a <VisualEditorProvider>.
import { useVisualEditor } from "@glokki-cms/react"
Signature
function useVisualEditor(): VisualEditorContextValue
VisualEditorContextValue
| Property | Type | Description |
|---|---|---|
componentTree | ComponentNode[] | Current component tree (from editor or fallback) |
selectedBlockId | string | null | ID of the currently selected block |
viewport | Viewport | Current viewport: "desktop" | "tablet" | "mobile" |
isEditorMode | boolean | Whether the page is loaded inside the CMS editor iframe |
registry | ComponentRegistry | The component registry passed to the provider |
editorOrigin | string | null | Origin of the CMS editor window, or null when not in editor mode |
isLibraryOpen | boolean | Whether the block library panel is open in the CMS sidebar |
isTreeSynced | boolean | true after the first tree:update message is received. Always true in non-editor mode |
editorToken | string | null | Current editor session token (refreshed periodically). null when not in editor mode |
Example
function MyBlock() {
const { isEditorMode, selectedBlockId, viewport } = useVisualEditor()
return (
<div>
{isEditorMode && <span>Editing</span>}
{viewport === "mobile" && <MobileLayout />}
</div>
)
}
Errors
Throws if called outside a <VisualEditorProvider>.
CMSPageEditor
Editor-aware page renderer. Reads the component tree from VisualEditorContext, wraps each block in <EditableBlock> for click/hover selection, and renders <InsertionIndicator> and <BlockGapInserter> for visual insertion feedback.
import { CMSPageEditor } from "@glokki-cms/react"
Props
None. Reads all state from VisualEditorContext.
Behavior
- Renders each block using the component registry with interactive editing wrappers
- Shows an empty canvas placeholder when the tree is empty (editor mode only)
- Renders insertion indicators at the computed insertion position when the block library is open
- Reports
tree:renderedback to the CMS after each render cycle
Example
<VisualEditorProvider registry={registry} pageSlug="/about">
<CMSPageEditor />
</VisualEditorProvider>
CMSPage
Static page renderer for non-editor contexts. Renders a component tree using a registry without any editor interactivity. Use this for published page rendering.
import { CMSPage } from "@glokki-cms/react"
Props
| Prop | Type | Required | Description |
|---|---|---|---|
componentTree | ComponentNode[] | Yes | The component tree from published page data |
registry | ComponentRegistry | Yes | Registry mapping block types to React components |
Example
<CMSPage componentTree={page.componentTree} registry={registry} />
PreviewBanner
Amber warning banner displayed at the top of the viewport during preview mode. Shows "Preview mode --- this page is not published" with a dismiss button. Uses inline styles so tenant apps don't need Tailwind or any CSS framework.
import { PreviewBanner } from "@glokki-cms/react"
Props
None.
Example
export default async function Page({ searchParams }) {
const { preview } = await searchParams
const isPreview = preview === "true"
return (
<>
{isPreview && <PreviewBanner />}
<MainContent />
</>
)
}
cmsMetadata()
Generates a Next.js Metadata object from a CMS page's SEO data. Handles title, description, canonical URL, robots, Open Graph, Twitter Card, and hreflang alternates.
import { cmsMetadata } from "@glokki-cms/react"
Signature
function cmsMetadata(
page: DeliveryPage | null,
options?: CmsMetadataOptions
): Metadata
CmsMetadataOptions
| Property | Type | Description |
|---|---|---|
baseUrl | string | Base URL of the tenant's site (e.g., "https://acme.editor.app"). Used for canonical URL and Open Graph URL generation |
env | string | Runtime environment (default: process.env.APP_ENV). Any value other than "production" — including unset — forces robots: { index: false, follow: false }, overriding the page's own robots directive |
Behavior
- Returns
{ title: "Page not found", robots: { index: false } }whenpageisnull - Non-production is always
noindex, nofollow. Unlessenv(orAPP_ENV) is exactly"production", robots are forced to{ index: false, follow: false }so staging and preview deploys are never indexed. SetAPP_ENV=productionon your production deployment, or every page will be de-indexed. In production, the page's stored robots string is honoured ("none"=noindex, nofollow) - JSON-LD is not included (Next.js Metadata API does not support it). Use the
<JsonLd>component separately
Example
import { cmsMetadata, JsonLd } from "@glokki-cms/react"
export async function generateMetadata({ params }) {
const { slug } = await params
const page = await cms.pages.getBySlug(slug)
return cmsMetadata(page, { baseUrl: "https://acme.editor.app" })
}
export default async function Page({ params }) {
const { slug } = await params
const page = await cms.pages.getBySlug(slug)
return (
<>
<JsonLd data={page.seo.jsonLd} />
<CMSPage componentTree={page.componentTree} registry={registry} />
</>
)
}
JsonLd
Renders JSON-LD structured data as <script type="application/ld+json"> tags. Escapes closing script tags to prevent XSS. Each item in the array becomes a separate script tag.
import { JsonLd } from "@glokki-cms/react"
Props
| Prop | Type | Required | Description |
|---|---|---|---|
data | SeoMetadata["jsonLd"] | Record<string, unknown> | Yes | JSON-LD objects from the page's SEO data. Accepts an array or a single object (legacy format) |
Renders nothing when data is undefined or an empty array, so you can pass page.seo.jsonLd without a guard.
Example
<JsonLd data={page.seo.jsonLd} />
FormBlock
Client component that renders a form built in the CMS (Forms), validates it in the browser, and submits it to the Delivery API. Field definitions, the success message, the redirect URL, and spam protection (honeypot, optional Turnstile/reCAPTCHA) come from the form's settings in the CMS.
import { FormBlock } from "@glokki-cms/react"
Props
| Prop | Type | Required | Description |
|---|---|---|---|
client | FormBlockClient | Yes | A delivery client from createClient() (anything with forms.getById and forms.submit). Memoize it. |
formId | string | Yes | The published form's id. |
initialForm | DeliveryForm | No | The form definition, fetched on the server, so the form renders without a client-side request. |
onSubmitSuccess | (response: { submissionId: string }) => void | No | Called after a successful submission, before the redirect (if the form has one). |
onSubmitError | (error: unknown) => void | No | Called with the raw error when submission fails. |
submitLabel | string | No | Submit button text. Default "Submit". Since 0.10.0. |
submittingLabel | string | No | Button text while the submission is in flight. Default "Submitting…". Since 0.10.0. |
Validation messages and the loading text are English and not yet configurable.
Styling
The component renders unstyled markup with stable hooks: the root carries data-form-block and data-status (loading, ready, submitting, success, error); the button has data-form-submit, and a submission error is a data-form-error element with role="alert".
Example
The form fetches and submits from the browser, so the client needs a key there: use a delivery key (delivery:read scope), which is meant to be public, and keep admin keys server-side.
"use client"
import { FormBlock } from "@glokki-cms/react"
import { createClient } from "@glokki-cms/sdk"
const client = createClient({
baseUrl: process.env.NEXT_PUBLIC_CMS_BASE_URL!,
tenantSlug: process.env.NEXT_PUBLIC_CMS_TENANT!,
apiKey: process.env.NEXT_PUBLIC_CMS_API_KEY!,
})
export function ContactForm({ formId }: { formId: string }) {
return (
<FormBlock
client={client}
formId={formId}
submitLabel="Send message"
submittingLabel="Sending…"
/>
)
}
CdnImage
Renders an image prop served through your /cdn/ route with a responsive srcSet and the asset's focal point. Any non-/cdn/ URL renders as a plain <img>. Since 0.10.0. Props and the generated markup are described in Asset CDN Proxy.
import { CdnImage } from "@glokki-cms/react"
;<CdnImage
src={image}
alt={alt}
width={1200}
height={800}
sizes="(min-width: 768px) 50vw, 100vw"
/>
createComponentRegistry()
Deprecated. Use
createBlockRegistry()from@glokki-cms/sdkinstead.
Creates a simple Map<string, Component> from a plain object. Does not support the v2 handshake, block metadata, or dynamic slots.
import { createComponentRegistry } from "@glokki-cms/react"
Signature
function createComponentRegistry(
components: Record<string, ComponentType<Record<string, unknown>>>
): ComponentRegistry
Migration
// Before (deprecated)
const registry = createComponentRegistry({
hero: HeroComponent,
cta: CtaComponent,
})
// After (recommended)
import { defineBlock, createBlockRegistry } from "@glokki-cms/sdk"
const HeroBlock = defineBlock({ type: "hero", ..., component: HeroComponent })
const CtaBlock = defineBlock({ type: "cta", ..., component: CtaComponent })
const registry = createBlockRegistry([HeroBlock, CtaBlock])
Additional Exports
The packages export several additional utilities and components beyond the primary APIs documented above. These are typically used for advanced integrations or internal purposes.
@glokki-cms/sdk — Additional
| Export | Description |
|---|---|
sendMessage(target, type, payload, origin) | Send a typed postMessage to the CMS or iframe |
onMessage(origin, handler) | Listen for typed postMessages from a specific origin. Returns a cleanup function |
createMessage(type, payload, seq?, version?) | Create a protocol-stamped message envelope |
isVisualEditorMessage(value) | Runtime type guard for visual editor messages |
buildEditorIframeUrl(params) | Construct the iframe src URL for the visual editor |
generateCollectionTypes(options) | Generate TypeScript types for a single collection |
generateAllCollectionTypes(options) | Generate TypeScript types for all tenant collections |
SDK_VERSION | SDK version string sent in the handshake request |
@glokki-cms/react — Additional
| Export | Description |
|---|---|
EditableBlock | Wrapper component for click/hover selection in editor mode |
BlockGapInserter | Click-to-insert button rendered between blocks in editor mode |
InsertionIndicator | Visual indicator showing where the next block will be inserted |
VisualEditorContext | Raw React context (use useVisualEditor() hook instead) |
SDK_VERSION | SDK version constant |
SDK Types
Key types exported from @glokki-cms/sdk:
Block Types
| Type | Description |
|---|---|
BlockRegistryEntry<TProps, TComponent> | Result of defineBlock() with pre-serialized field descriptors |
DefineBlockConfig<TSchema, TComponent> | Configuration object passed to defineBlock() |
BlockCategory | A block's category key — a free-form string, not a closed union (the tenant declares its own set) |
BlockCategoryDefinition | One declared category: { key: string, label: string } |
SerializedBlockCategory | Wire form of a category — identical to BlockCategoryDefinition |
BlockRegistryOptions | Second argument to createBlockRegistry(): { categories?: BlockCategoryDefinition[] } |
BlockRegistry | Registry interface returned by createBlockRegistry() |
SerializedBlockDefinition | Wire-safe block definition sent during iframe handshake |
SlotDefinition | Named slot area where child blocks can be dropped |
SerializedSlotDefinition | Wire-safe slot definition (static or dynamic) |
BlockViewportOverrides<TProps> | Per-viewport prop overrides for block definitions ({ tablet?: Partial<TProps>, mobile?: Partial<TProps> }) |
ViewportOverrides | Non-generic viewport overrides for delivery API wire types |
Delivery API Types
| Type | Description |
|---|---|
ClientOptions | Options for createClient() |
CMSClient | Client type returned by createClient() |
DeliveryPage | Published page with component tree, SEO, code injection |
DeliveryPageListItem | Lightweight page item from the list endpoint |
ComponentNode | A node in the component tree (id, type, props, children, slot, viewportOverrides) |
SeoMetadata | SEO fields: meta title, description, canonical, robots, OG, Twitter, JSON-LD |
CodeInjection | Custom <head> and <body> code snippets |
NavigationItem | Published page navigation entry (slug, title, locale) |
DeliveryRedirect | Redirect rule (source, target, type, isRegex, preserveQueryString) |
PaginationMeta | Pagination metadata (total, limit, offset) |
ApiError | Error response shape from the Delivery API |
AlternateLocale | Alternate locale link for hreflang (locale, url) |
ExperimentMeta | A/B experiment metadata (experimentId, variantId, variantName, isControl) |
VariantResolution | Variant resolution result (extends ExperimentMeta with pageId) |
Collection Types
| Type | Description |
|---|---|
DeliveryCollection | Collection with fields schema, sort config, and URL prefix |
CollectionEntry | Published collection entry with collectionData, SEO, and tags |
CollectionEntryTag | Tag attached to an entry (id, name, slug) |
CollectionEntriesPagination | Pagination for entries (page, limit, total, totalPages) |
CollectionFieldDefinition | Field definition within a collection schema |
CollectionFieldType | Field types: "text", "textarea", "richtext", "number", "date", "datetime", "boolean", "url", "image", "file", "select", "multiselect", "relation", "dataModelRef", "dataModelRefs", "json" |
ListCollectionEntriesOptions | Options for listing collection entries |
Field Descriptor Types
| Type | Description |
|---|---|
FieldDescriptor | Serialized field definition for the CMS props panel |
FieldType | Field type string used in descriptors |
FieldValidation | Validation rules (min, max, pattern, etc.) |
JsonValue | JSON-safe value type |
Visual Editor Protocol Types
| Type | Description |
| --------------------- | -------------------------------------------------- | --- |
| VisualEditorMessage | Base message type for CMS <-> iframe communication |
| ProtocolVersion | Protocol version number (1 | 2) |
| CMSToIframeMessage | Union of all message types from CMS to iframe |
| IframeToCMSMessage | Union of all message types from iframe to CMS |
| Viewport | "desktop" \| "tablet" \| "mobile" |
Protocol Constants
| Export | Value | Description |
|---|---|---|
PROTOCOL_VERSION | 2 | Current protocol version (numeric) |
SUPPORTED_VERSIONS | [1, 2] | Supported protocol versions (numeric array) |
NAMESPACE | "__editorCms" | Message namespace guard — filters foreign postMessage events |
EDITOR_QUERY_PARAM | "_editor" | URL param that enables editor mode |
EDITOR_ORIGIN_QUERY_PARAM | "_editorOrigin" | URL param containing the CMS origin |
EDITOR_TOKEN_QUERY_PARAM | "_editorToken" | URL param containing the editor session token |
EDITOR_LOCALE_QUERY_PARAM | "locale" | URL param for locale override inside the editor iframe |
React Types
Key types exported from @glokki-cms/react:
| Type | Description |
|---|---|
VisualEditorProviderProps | Props for <VisualEditorProvider> |
VisualEditorContextValue | Return type of useVisualEditor() |
ComponentRegistry | Map<string, ComponentType> mapping block types to components |
CmsMetadataOptions | Options for cmsMetadata() |
EditableBlockProps | Props for the <EditableBlock> wrapper (internal) |
BlockGapInserterProps | Props for <BlockGapInserter> (internal) |
InsertionIndicatorProps | Props for <InsertionIndicator> (internal) |