Add a custom block
Write your own block component, register it beside the library's blocks, and give it fields in the CMS.
Scaffold the component. The name becomes the file
src/blocks/PromoBanner.astroand the block typepromoBanner.pnpm stomme block new promo-bannerBuild its markup with the library's classes (
.section,.display,.card, …) or a scoped<style>, and colour it with the theme's CSS variables. Styles shows each class and variable.Create
src/blocks/BlockRenderer.astro, a thin wrapper that passes your blocks to the engine's renderer.--- import Engine from '@gronare/stomme/BlockRenderer.astro'; import PromoBanner from './PromoBanner.astro'; const props = Astro.props; --- <Engine {...props} registry={{ promoBanner: PromoBanner }} />The CMS preview and
/lookbookpick this file up on their own.Import the wrapper in the pages that render blocks,
src/pages/index.astroandsrc/pages/[...slug].astro.import BlockRenderer from '../blocks/BlockRenderer.astro';Add the block's fields to the catalog in
src/blocks/schema.ts.import { defaultBlocks } from '@gronare/stomme/catalog'; import { headingFields, layoutGroup, styleGroup, surfaceField, type BlockDef } from '@gronare/stomme/kit'; export const BLOCKS: BlockDef[] = [ ...defaultBlocks, { type: 'promoBanner', label: 'Promo banner', group: 'Calls to action', fields: [...headingFields, layoutGroup([]), styleGroup([surfaceField])], samples: [{ heading: 'Ten percent off this month' }], }, ];Regenerate the CMS.
pnpm stomme cmsThe output lists
promoBannerunder the custom blocks, and Promo banner appears in the CMS's section picker.
layoutGroup gives the block layout.beside, and styleGroup([surfaceField]) gives it style.surface. The renderer handles both for every block, yours included. samples is what /lookbook shows. Field kit lists every helper.
Replace or extend a built-in block
A custom type wins over a library type with the same key. Register a component as hero and it renders every hero block.
To extend rather than replace, handle your own case and hand the rest back to the engine's block.
---
// src/blocks/Hero.astro
import EngineHero from '@gronare/stomme/blocks/Hero.astro';
const props = Astro.props;
---
{props.media?.kind === 'diagram'
? <section class="section hero-grid"><!-- your own media --></section>
: <EngineHero {...props} />}
Register it in the wrapper as registry={{ hero: Hero }}. A new value such as diagram renders from content right away. To offer it in the CMS, add it to the hero's media.kind options in src/blocks/schema.ts and run pnpm stomme cms.
Import engine files by their published names, such as @gronare/stomme/Header.astro and @gronare/stomme/blocks/Hero.astro. Other paths inside the package are not stable.