Block System

How blocks work in the headless model - defineBlock, instances, the component, context, and the data loader.

June 29, 2026

Overview

Blocks are the building units of every Cmssy page. In the headless model a block is a React component in your own Next.js repo, declared with defineBlock and a fields schema. The Cmssy admin lets editors place and configure block instances; your site renders them with the SDK. A block has three parts:

  • Schema (fields) — the editable fields shown in the admin
  • Component — the React component that renders the content
  • Registration — the block added to your cmssy/blocks.ts array

Defining a block

A block is declared with defineBlock and a fields schema, and its component derives its props from that same schema with BlockProps<typeof props> - so a field is named in exactly one place. Block development walks through it end to end; Schema & field types lists every field type.


Block instances

When an editor adds your block to a page, Cmssy stores a block instance:

{
  id: string;    // unique UUID for this instance
  type: string;  // matches your block's `type` (e.g. "hero")
  content: Record<string, unknown>;  // language-keyed field values
}

Content is stored per language ({ en: {...}, pl: {...} }); the SDK resolves the active locale before passing content to your component, so you read fields directly.


The component, context & data

Your component receives { content, context, data }. content is already resolved for the active locale and typed from your schema; context carries locale and isPreview, plus forms, and auth / workspace when your app supplies them through buildBlockContext; data is whatever a server loader returned.

Registration is one array, cmssy/blocks.ts, and it is the single source of truth: it drives rendering, and the editor learns each block's schema from it over the SDK bridge, so the picker always matches what your site can render. Blocks ship when you deploy your app - there is no separate block build or publish step.


Layout blocks

Header, footer and other shared regions are layout blocks — the same as page blocks but tagged with layoutPositions (e.g. ["header"]) and rendered by CmssyServerLayout per position.


Internationalization

Content is language-keyed in the CMS and resolved per request. Routing is by path prefix (/pl/*), with the default locale using clean URLs. Read the active and enabled locales from context.locale.


Next Steps