@407dev/cms-astro
v1.0.2
Published
- Astro SDK & integration providing declarative field helpers (`f.text`, `f.img`, `f.richText`, `f.scope`, `f.entryScope`, `f.group`, `f.entries`), ProseMirror `<RichText>` rendering, build-time bundle hydration, preview bridge protocol injection, token-g
Readme
@407dev/cms-astro
Purpose
- Astro SDK & integration providing declarative field helpers (
f.text,f.img,f.richText,f.scope,f.entryScope,f.group,f.entries), ProseMirror<RichText>rendering, build-time bundle hydration, preview bridge protocol injection, token-gated draft preview overlays, and an in-browser dev toolbar app for live editing during local development with zero drift.
Surface
- Declarative field helpers & scopes: src/fields/index.ts (
f,f.text,f.img,f.video,f.richText,f.number,f.toggle,f.select,f.videoList,f.geoArea,f.addressList,f.scope,f.entryScope,f.collectionAttrs,cmsCollectionAttr,f.group,defineCollection,collectionPaths) - Collection factories (
@407dev/cms-astro/collections): src/fields/collections.ts (defineEmailCampaignCollection,defineSmsCampaignCollection) - Dynamic dual-callable helper generator derived from
@407dev/field-types: src/fields/helpers.ts - Scope & key prefixing: src/fields/scope.ts
- Entry scoping: src/fields/entryScope.ts (
f.entryScope) - Group definition & accessor binding: src/fields/group.ts
- Collection handle & routing: src/fields/collection.ts (
collectionAttrs) - ProseMirror RichText renderer: src/RichText.astro & src/richtext/render.ts
- Preview bridge script generator: src/preview/bridge-script.ts
- Dev toolbar app & UI: src/toolbar/app.ts & src/toolbar/widgets.ts
- Dev config & credential gate: src/dev/config.ts & src/dev/token.ts
- Dev API routes middleware: src/dev/routes.ts
- Dev AST verifier service: src/dev/verifier.ts
- Runtime bundle store & AsyncLocalStorage overlay: src/runtime/store.ts (
getActiveBundle,runWithDraftBundle,setBuildBundle) - Client factory & bundle fetcher: src/client.ts (
createCmsClient,initCmsClient,getClient) - Image transforms & srcset: src/image.ts
- Head & SEO tag builder: src/head.ts
- Static site file generators: src/siteFiles.ts (
renderRedirectsFile,renderRobotsTxt,renderSitemapXml) - Preview middleware & draft bundle retrieval: src/middleware/preview.ts & src/preview.ts
- Astro integration definition: src/integration.ts (
cmsAstro,cms) - Package entrypoint: src/index.ts
Patterns
- Usage is the Schema: Reading
f.text('home.hero.heading')or<f.text k="home.hero.heading" />simultaneously marks the DOM editable region and defines the manifest entry for static extraction. - Dual-Callable Helpers: Helpers work synchronously as functions (
f.text('key', { defaultValue: '...' })) returning typed primitives or as Astro JSX components (<f.text k="key" />) emitting DOM marker attributes (data-cms-field,data-cms-entry-field). - Entry Scoping & Collection Listings:
f.entryScope('blog', entry.slug)creates bound helpers emittingdata-cms-entry-fieldand provides.attrs()emittingdata-cms-collection+data-cms-entry.f.collectionAttrs('blog')emitsdata-cms-collectionon listing containers for visual canvas collection editing. - Group Multiplication:
f.groupdefines reusable multi-field shapes instantiated at different prefixes (Hero('home.hero'),Hero('about.hero')), passing bound helpers to prop-drilled components. - Preview Bridge Injection: In preview requests (
/_preview/*?preview_token=...) and Astro dev mode, the bridge IIFE is injected before</body>to handle handshake, capabilities (capabilities: ['comments', 'collection-click']), click capturing (field -> group -> entry -> collection priority), collection outlines with dashed borders and label chips, comment mode click suppression, anchor chain derivation, liveanchor-rectsstreaming, outlines, and DOM patching. - Dev-Server Middleware API: In dev mode (
command === 'dev'), Vite middleware mounts/_cms/dev/*for status, bundle, and draft field writes without polluting production bundles. - Single Bundle Fetch: Published bundle is fetched once per build and hydrated across all static pages synchronously via store singleton and
.cms/bundle.json. - Zero-Config Integration:
cmsAstro()accepts no arguments, automatically falling back to environment variablesCMS_SITE_IDandCMS_CONTENT_URLpopulated bycms link(preview secrets are never stored on site hosts; preview tokens are verified directly by content-worker). - AsyncLocalStorage Draft Overlay:
runWithDraftBundleoverlays draft field values and entries inside SSR preview requests without mutating the global store.
Integrations
- Consumes
@407dev/blocks(packages/blocks) for deterministic schema hashing and schema parsing. - Consumes
@407dev/field-types(packages/field-types) for field registry, validation, and link whitelisting. - Consumes
@407dev/config(packages/config) for dev tokens and path normalization. - Optionally consumes
@407dev/cli(packages/cli) in dev mode for real-time template AST extraction diagnostics. - Consumed by consumer Astro applications (e.g.
examples/demo-site(examples/demo-site)).
Constraints
- Published to public npm with ESM output and
.d.tsdeclaration maps viatsup. - Any export change or signature alteration requires a changeset (
pnpm changeset). - Zero direct database queries — communicates exclusively via edge content and draft HTTP endpoints.
- Separate preview build topology: preview deployment sets
CMS_PREVIEW_BUILD=1->output: 'server'+ Cloudflare adapter, whereas production builds default tooutput: 'static'. A site may still carry the Cloudflare adapter in a static production build to run other on-demand routes (e.g.@407dev/site-services's injected/_api/[...path]) via per-routeprerender: false— the adapter alone does not make the whole site server-rendered. - Dev routes and toolbar code are strictly excluded from production build outputs (
astro build).
Gotchas
CMS_DEV_TOKENis never exposed to the client or injected intovite.define; it is used exclusively by dev-server middleware for write-plane authorization.- In Astro preview middleware,
context.rewrite(targetPath)must be returned directly to render the rewritten route; discarding its return value results in rendering nonexistent/_preview/*routes. - When rendering group fields in prop-drilled components, use bound accessors (
content.heading) and spread{...content.attrs()}— do not callf.text('literal')internally inside shared components. - Invalid or expired preview tokens return
404 Not Found(never exposing error details or unauthenticated drafts). - Preview responses must always be served with
Cache-Control: no-storeandX-Robots-Tag: noindex. - When mutating the DOM during in-place toolbar saves, MutationObservers are paused to avoid triggering re-entrant rescan loops.
- Preview bridge and dev status editor origins are configured via
CMS_EDITOR_ORIGINS(comma-separated) or expliciteditorOriginsintegration options; defaults to allowing bothhttps://web.localhostandhttp://localhost:5173. - The injected preview bridge automatically suppresses the Astro dev toolbar (
astro-dev-toolbar { display: none !important; }) when loaded inside an<iframe>(editor preview). - Comment mode cursor and click interception takes precedence over visual edit mode and link navigation whenever
data-cms-comment-modeis set ondocument.documentElement.
