Skip to content

Static delivery

Static delivery lets a normal static Astro site use CaretCMS without a CMS server in production. Editors still get inline editing and Studio in astro dev; published content is baked into generated HTML at build time.

Use static delivery when…Use server delivery when…
Your site ships as static files (Netlify, Vercel static, S3, CDN)You already run Astro with output: 'server'
Publish → rebuild → deploy is acceptable for public updatesYou need visitor-visible edits immediately after save
You want CaretCMS without an SSR adapterYou want per-request HTML rewriting in production
Dev (astro dev)
→ CaretCMS injects /admin, /api/cms, inline editor (local authoring)
Build (astro build, output: static)
→ Authoring routes stay out of production output
→ astro:build:done bakes .caret/data overrides into dist/**/*.html
Publish
→ Draft overlay commits to storage
→ Optional rebuild webhook triggers CI → astro build → deploy

Your template markup remains the seed content. Until an editor saves an override, visitors see the original HTML. After publish and rebuild, stored values replace tagged fields in the built files.

  1. Wire the integration

    astro.config.mjs
    import { defineConfig } from 'astro/config';
    import caret from '@caretcms/core';
    export default defineConfig({
    integrations: [caret({ delivery: 'static' })],
    });

    npx @caretcms/caretize init scaffolds this automatically for static Astro projects.

  2. Tag editable content

    Add data-caret attributes by hand or run npx @caretcms/caretize. Same binding model as server delivery — see Inline editing.

  3. Author locally

    Terminal window
    npm run dev

    Sign in at /admin. With no CARET_EDIT_PASSWORD set, a temporary dev password prints in the terminal.

  4. Ship baked HTML

    Terminal window
    npm run build

    Look for [caretcms] static delivery bake complete (N/N HTML files rewritten). Deploy dist/ to your static host — no CMS routes in production output.

astro.config.mjs
caret({
delivery: {
mode: 'static',
bake: true,
publish: {
webhookUrl: process.env.CARET_REBUILD_WEBHOOK_URL,
method: 'POST',
headers: { authorization: `Bearer ${process.env.CI_TOKEN}` },
},
},
})

After Publish, the webhook receives:

{
"source": "caretcms",
"event": "publish",
"published": [{ "collection": "pages", "id": "home", "revision": 3, "deleted": false }],
"commit": "abc123..."
}

The publish still succeeds if the webhook fails — check logs and retry the deploy.

OptionDefault (static)Notes
delivery: 'static'Shorthand for { mode: 'static', bake: true }
delivery.mode'server' if omittedMust be 'static' for this path
delivery.baketrue when mode is staticSet false to skip HTML rewrite at build
delivery.publish.webhookUrlnoneCalled after successful publish
delivery.publish.methodPOSTPOST or PUT
delivery.publish.headers{}Extra headers for the webhook

See Configuration for all caret() options.