Skip to main content

Custom Block Registration

Use custom blocks when your site has its own component library and you don’t want the product’s default block set (Hero, CTA, FeatureGrid, etc.). Default blocks are a starter kit — convenient for new sites but not required. The product is content-model-agnostic: it works with any blocks you register.

How it works

  1. You define a block manifest — an array of BlockDefinition objects describing your block types
  2. You pass it to the Content Studio API handler via getManifest()
  3. The AI planner, property panel, and block picker in the Content Studio all derive their behavior from your manifest
  4. Your site renders blocks with your own React components

Minimal example

1. Define your manifest

2. Wire into the editor API route

3. Verify

Start your dev server and check:
Should print your block types. The Content Studio header should show Manifest (not Degraded).

BlockDefinition reference

propsSchema

Uses a JSON Schema subset. The product infers field types from schema + field name conventions: You don’t need to explicitly declare field kinds — the product derives them from your schema. Name image fields *imageUrl or *Image and they’ll be detected automatically.

defaultProps

Provide sensible defaults for every field. When a user asks the AI to “add a Hero block”, these defaults are used as the starting point. The AI then modifies them based on the user’s request.

editablePaths (optional)

JSONPath-style strings hinting which fields the AI should focus on. Not required — the AI infers editability from the schema. Useful for complex blocks where you want to limit AI scope.

Image handling

If your blocks have image fields, the manifest-driven image detection handles them automatically:
The getManifestImageFields() utility derives this from your propsSchema — fields matching the image name pattern are included automatically.

Rendering blocks

The product doesn’t render your custom blocks — your site does. Map block.type to your React components:
Or use the SDK’s renderBlocks() if you register renderers with the block system.

Using with a CMS

Custom blocks work with any CMS adapter. The pattern is the same as default blocks:
  1. Fetch: Query your CMS → convert to PageDoc with BlockInstance[]
  2. Publish: Receive PageDoc[] → write back to your CMS
  3. Image fields: Use imageFields from your manifest (not getImageFields() from the shared registry)
The create-ai-site-editor scaffold supports custom blocks — choose “Custom blocks” when prompted and it generates a stub manifest for you to fill in.

Mixing default and custom blocks

You can use both default blocks and custom ones. Import buildBlockManifest() for the defaults and merge:

Checklist

  • Create lib/manifest.ts with your BlockDefinition[]
  • Pass getManifest to createEditorApiHandler()
  • Verify /api/editor/blocks returns your blocks
  • Content Studio header shows Manifest (not Degraded)
  • Add block picker shows your block types
  • AI can create, edit, and remove your blocks
  • Image fields are detected (check publish resolves images)