Skip to main content
StormyCMS

Components and schema

Register React components in packages/components/src/index.ts. Both apps import this map to render content and build the editor's forms.

Add a component

Create packages/components/src/lib/notice.tsx:

type NoticeProps = { text: string };
export function Notice({ text }: NoticeProps) {
return <aside>{text}</aside>;
}

Import it into packages/components/src/index.ts and add this entry to the existing default export:

import { Notice } from './lib/notice';
// Inside the existing export map:
Notice: withCMS(
{
export: 'Notice',
label: 'Notice',
fields: [
{ label: 'Text', prop: 'text', field: 'textarea', required: true, defaultValue: '' },
],
noChildren: true,
},
Notice,
),

The starter already imports withCMS. Open a page in the admin and insert Notice.

The map key, export, and stored component name must match. Unknown names do not render. If the parent restricts validChildren, add Notice to that list too.

Set placement rules

Use component names in validChildren and validParents to restrict nesting. Set noChildren: true for a leaf component, layoutOnly: true for layout components, or unique: true for one instance per parent.

Keep Outlet in the map. Place it in each layout where page content should appear. To nest layouts, select a parent layout in the layout editor.

Generate a draft from props

Terminal window
pnpm exec stormy generate --components packages/components/src/lib --output packages/components/draft.ts --framework react

Generate to a separate file. Generation overwrites its output and still needs import and schema fixes. Follow the CLI reference before merging it into your map.

See the React reference for registration options and the field reference for editor controls.

Last updated: 10/20/26, 1:09 AM

StormyCMS

The headless CMS where you own the editor.