Quickstart
This guide takes an existing Astro site from installation to a published text change. Start with local editing and a static build. You can choose server delivery afterward without changing your HTML bindings.
You need Astro 6 or 7, Node 22.12 or newer, and a working Astro project. Run the commands from that project’s root. The examples use npm; pnpm and Yarn work too.
Already have Markdown content you want to edit in place? Follow Markdown body editing instead. Starting a new project? See Plug-in or starter.
1. Install CaretCMS
Section titled “1. Install CaretCMS”npm install @caretcms/core@0.5.0For an automated setup, Caretize can install the integration and add bindings to existing templates. The steps below show the manual path.
2. Configure local editing
Section titled “2. Configure local editing”Add caret() to your existing integrations. This complete minimal configuration
uses JSON files explicitly, so the example behaves the same whether or not your
project already has a src/content/ directory:
import { defineConfig } from 'astro/config';import caret, { filesystemStorage } from '@caretcms/core';
export default defineConfig({ integrations: [ caret({ delivery: 'static', storage: filesystemStorage(), }), ],});Keep your project’s other integrations and options. This path uses Astro’s
static output and needs no server adapter. If your site already uses
output: 'server', use the server configuration below
instead.
CaretCMS adds a login page at /admin and Studio at /admin/cms during local
development. Public static builds do not include these authoring routes.
3. Make a field editable
Section titled “3. Make a field editable”Add a binding to an existing element in src/pages/index.astro:
<main data-caret-scope="pages::home"> <h1 data-caret="headline">Welcome to my site</h1> <p data-caret="intro">This text can be edited on the page.</p></main>The parent selects collection pages and entry home. Each child names a field on that entry. You can also write a complete binding on one element:
<h1 data-caret="pages::home::headline">Welcome to my site</h1>The template text is the default. Saved content replaces it; the editor does not
rewrite your .astro template. No schema or pre-created JSON file is needed
for this first text edit.
4. Sign in and save an edit
Section titled “4. Sign in and save an edit”Create a local .env file with a development password and a session secret:
CARET_EDIT_PASSWORD=choose-a-local-development-passwordCARET_SESSION_SECRET=paste-a-generated-secret-hereGenerate the secret with this command and paste the output into the second line:
node -e "console.log(require('crypto').randomBytes(32).toString('base64url'))"Keep .env out of git. Production credential setup is covered in
Authentication.
Start Astro with that file loaded into the Node process environment:
node --env-file=.env ./node_modules/astro/bin/astro.mjs devThis starts Astro directly with Node 22.12+. Loading the file explicitly
matters: CaretCMS reads credentials from the process environment. If your shell
or host already supplies them, npm run dev is sufficient.
- Open
/adminon the local URL printed by Astro, usuallyhttp://localhost:4321. - Sign in, then return to the home page.
- Click the headline and change its text.
- Click outside the field or press Cmd/Ctrl+S to save.
- Wait for Draft saved before publishing. You can also open the entry in Studio to check its saved values.
At this point you have a saved private draft. Visitors do not see it yet. Keep this password session open until you publish: signing out makes its private drafts inaccessible. See draft ownership.
5. Publish and build
Section titled “5. Publish and build”Choose Publish in the page editor. After publication succeeds, run:
npm run buildnpm run previewOpen the preview URL printed in the terminal. It should show your changed
headline without an editor toolbar. Deploy the dist/ folder to your static host.
If CI builds the site, it must receive the published content files too; a rebuild
request alone does not transfer them.
Edit -> Save draft -> Publish -> Build -> Deploy private shared HTML visitors see itWith this configuration, published values live in .caret/data/, private drafts
in .caret/drafts/, and revisions/history in .caretcms/. Persist the folders
your workflow needs and exclude private drafts from commits. See
Static delivery for the complete deployment workflow.
Add images and structured fields
Section titled “Add images and structured fields”To replace an image on the page, bind its URL field. Use an image that already
exists in your project’s public/ directory:
<img data-caret="pages::home::hero" src="/images/hero.jpg" alt="" />The image picker uploads a replacement and saves its URL. Configure alternative text as a separate Studio field. Include local uploads in the next static build and deployment.
Open /admin/cms to edit entries in a form. Add a schema when
you need clear labels, required fields, image controls, or repeatable records.
Use server delivery
Section titled “Use server delivery”Use server delivery if the site should run as an Astro server and read changes on each request. For Node hosting, install a compatible Astro adapter:
npm install @astrojs/nodeimport { defineConfig } from 'astro/config';import node from '@astrojs/node';import caret, { filesystemStorage } from '@caretcms/core';
export default defineConfig({ output: 'server', adapter: node({ mode: 'standalone' }), integrations: [caret({ storage: filesystemStorage() })],});Ordinary field saves now update shared content; they are visible on a new request. An active write policy makes those saves private drafts. Markdown body edits always require Publish. Production Node hosting also needs persistent storage and authentication; follow Deployment.
If something does not work
Section titled “If something does not work”- No editing controls: sign in and check the binding spelling and parent scope.
- Saved change missing from the preview build: Publish first, then rebuild.
- No
/adminon the deployed static site: expected; edit in the authoring environment.
Continue with Inline editing, Content Studio, or Troubleshooting.