Skip to content

Demo / Sandbox Mode

Demo mode turns a deployment into a public sandbox: anyone can click and edit the page without a password, and every visitor gets their own isolated copy of the content. It’s how the live demo works — try it, edit a headline, and your changes stay private to your browser.

When CARET_DEMO_MODE=true:

  • The middleware mints a caret_demo_session cookie on first request (2-hour sliding window) and treats that visitor as an authorized editor — no login, no shared password.
  • Every write goes to a per-session overlay layered over the shared base content. Reads return base content plus that session’s own edits; deletes are tombstoned in the overlay.
  • Sessions never see each other’s edits, and the canonical base content is never mutated by visitors. When a session’s cookie expires (or the visitor closes the tab), their sandbox is gone.
  1. Deploy on Cloudflare Workers with KV + R2, following Deployment → Cloudflare Workers.

  2. Set CARET_DEMO_MODE as a Worker variable.

    wrangler.toml
    [vars]
    CARET_DEMO_MODE = "true"

    No editor password is required in demo mode, but you can still set CARET_SESSION_SECRET for signed cookies.

  3. Seed the starting content. Demo sessions overlay whatever is in your base store. Commit starter entries to .caret/data/ so the bundled fallback seeds KV, or write them in once. Every visitor begins from this snapshot.

To keep a public sandbox cheap and abuse-resistant, demo uploads are capped per session. Defaults are 5 MB per file and 25 MB per session; tune them on r2Uploads():

astro.config.mjs
import { r2Uploads } from '@caretcms/cloudflare';
r2Uploads({
binding: 'CMS_R2',
sandboxPerFileBytes: 5 * 1024 * 1024, // default: 5 MB
sandboxPerSessionBytes: 25 * 1024 * 1024, // default: 25 MB
})

A visitor who exceeds the per-file cap gets File too large (5MB max in sandbox); exceeding the session cap gets Sandbox storage full — close this tab to start a fresh session. These limits apply only in demo mode — normal deployments upload without them.

LayerIn demo mode
AuthA caret_demo_session cookie stands in for the editor session; no password check
StorageSessionOverlayAdapter wraps your base adapter — reads merge base + overlay, writes hit the overlay, deletes tombstone
UploadsQuotaUploadHandler wraps your upload handler with per-file / per-session byte caps
Lifetime2-hour sliding TTL on the cookie; no persistence guarantees