@saacms/blocks-essentials
v0.1.9
Published
**Status:** scaffold (v0.1.0). Not yet wired into a host app.
Readme
@saacms/blocks-essentials
Status: scaffold (v0.1.0). Not yet wired into a host app.
The built-in Block library shipped with saacms. Currently exports the Hero block.
Authoring mode
All built-in blocks are authored as Web Components (Mode 1 per ADR 0004 — Block authoring: dual mode).
Web Components are framework-agnostic by construction: the same <saacms-hero> element
renders identically whether the host framework is Astro, Next.js, SvelteKit, or Nuxt.
This is why the built-ins choose Mode 1 — one bundle, every host.
Block authors who want host-framework-native ergonomics (React hooks, Svelte stores, scoped CSS) should choose Mode 2 (framework-native) for their own blocks. The built-ins stay portable.
Reactivity
Reactive state inside the Web Components uses the cross-framework signal primitive
from @preact/signals-core per
ADR 0023 — Frontend state and backend-driven sync.
The eventual migration target is the TC39 Signals proposal; the wrapper is a one-line swap.
Usage
import { register } from "@saacms/blocks-essentials"
// Call once at app boot — registers all built-in custom elements.
register()After registration, the elements are available as standard custom elements:
<saacms-hero
title="Ship faster"
subtitle="A CMS that respects your stack."
cta-label="Get started"
cta-href="/signup"
></saacms-hero>Notes on this scaffold
- No shadow DOM — the Hero component renders into its light DOM for v1 simplicity. This means the host page's CSS reaches in and styles the block, which is the intentional v1 behaviour (matches editor preview ergonomics). Shadow DOM with slotted content is a candidate for a v2 hardening pass once the styling story crystallises.
- Observed attributes are kebab-case per the HTML standard
(
title,subtitle,cta-label,cta-href); the block schema uses camelCase (ctaLabel,ctaHref) and saacms's compile step bridges the two.
Known reconciliation TODO
src/hero/Hero.block.ts defines a local BlockDef type. Once @saacms/core's defineBlock is fully exported and the contract test suite locks the shape, swap the local type for the canonical import.
