@webmodern/cms-sdk
v0.4.0
Published
Shared SDK: <Editable> (incl. richtext-accenten), <EditableImage> (incl. remote/CDN-uploads), CmsEditor (visuele editor), Supabase client + types
Readme
@webmodern/cms-sdk
Shared SDK voor alle WebModern apps. Gebruikt door zowel apps/cms als apps/site-starter (en alle geforkte klantsites).
Status: TODO
Scaffolding gepland in sessie 2. Hieronder wat de API straks wordt.
Geplande API
Components
import { Editable, EditableImage } from "@webmodern/cms-sdk";
// Tekst (server component fetcht, of client component met SSR fallback)
<Editable
blockId="hero-title"
type="heading" // 'heading' | 'text' | 'richtext' | 'url'
defaultValue="Welkom" // gebruikt als CMS leeg is
/>
// Richtext: `*woord*` in de waarde wordt een accent-span, newline een <br/>.
// De site bepaalt de accent-stijl via accentClassName; de klant markeert in
// het CMS alleen wélke woorden het accent krijgen (sterretjes typen).
<Editable
as="h1"
className="hero-title"
blockId="hero-title"
type="richtext"
accentClassName="script-accent"
defaultValue="Hier krijg je *overzicht* en *rust.*"
/>
// Afbeelding
<EditableImage
blockId="hero-image"
defaultSrc="/placeholder.jpg"
defaultAlt="Hero illustratie"
width={1200}
height={630}
priority // optioneel, voor LCP
/>
// Klanten kunnen via het CMS een nieuwe afbeelding uploaden; `value` wordt dan
// een CDN-URL (CloudFront). Remote bronnen rendert <EditableImage> automatisch
// `unoptimized` (werkt zo ook op Cloudflare Pages, zonder Vercel-optimizer).
// Op Vercel-forks: voeg het CDN-domein toe aan next.config images.remotePatterns.Visuele editor (CmsEditor)
Eén keer in de root-layout van de klantsite plaatsen. Doet niets tenzij de
pagina met ?edit=1 in een iframe binnen het CMS draait; dan maakt het de
<Editable>-blokken klikbaar en toont het de concepten die het CMS via
postMessage stuurt (de site leest zelf nooit concepten — zie src/editor/protocol.ts).
import { CmsEditor } from "@webmodern/cms-sdk";
// app/layout.tsx (client of server layout)
<body>
{children}
<CmsEditor /> {/* optioneel: allowedOrigins={["https://cms.webmodern.nl"]} */}
</body>Het gedeelde postMessage-protocol staat in @webmodern/cms-sdk/editor (types +
isAllowedCmsOrigin), zodat het CMS dezelfde berichtdefinities gebruikt.
Hooks (client-side)
import { useContent, useSite } from "@webmodern/cms-sdk";
const content = useContent("hero-title"); // string
const site = useSite(); // { id, name, slug, brand }Server helpers
import { getContent, getSite } from "@webmodern/cms-sdk/server";
export default async function Page() {
const title = await getContent("hero-title", { siteId: SITE_ID });
return <h1>{title}</h1>;
}Types
import type { Site, ContentBlock, ContentBlockType } from "@webmodern/cms-sdk/types";Architectuur
- Database client: Supabase met auto-generated types via Drizzle
- Edit-mode detection:
?edit=1query param activeert inline editor (alleen als ingelogd in CMS) - Caching: Server-side fetches via React
cache()+ Next.jsrevalidateTagpersiteId - Realtime: Supabase Realtime channel per
siteIdvoor instant CMS preview
