Quickstart
Louise is a toolkit for building editable sites on Astro + Cloudflare Workers—content, commerce, media, forms, auth, and AI as composable primitives. Editing the live page in place is the headline; this page gets you from zero to it.
See it first (30 seconds)
Section titled “See it first (30 seconds)”You don’t have to install anything to evaluate Louise:
- Interactive examples—each primitive as live UI beside the real, drift-proof source that ships it. The contact form and Workers checkout run today.
- Live sandbox—a real, write-capable Louise site that resets nightly. Toggle edit mode and change anything; nothing you do sticks around.
This whole docs-and-marketing site is itself built with Louise, so the demos are the product.
Add it to your app (≈5 minutes)
Section titled “Add it to your app (≈5 minutes)”The steps below wire inline editing into an existing Astro on Cloudflare Workers
app (the @astrojs/cloudflare
adapter, with a D1 binding on env.DB). Inline editing is progressive
enhancement—you server-render normally, then mark the editable regions and
mount the client in edit mode.
1. Install
Section titled “1. Install”pnpm add louise-toolkit# peers for what this quickstart uses: Drizzle (db) + the inline-edit clientpnpm add drizzle-orm solid-js prosekit @prosekit/pmLouise’s heavier dependencies are optional peers—a route that only imports
louise-toolkit/errors pulls in nothing extra. Install peers per export you use.
2. Mark a region as editable
Section titled “2. Mark a region as editable”The marker is "<collection>:<key>:<field>"—the collection, the row key, and
the field the client will PATCH.
---// src/pages/index.astro — render the value from your own D1 row as usual.const settings = /* your Drizzle query over env.DB */;---<h1 data-louise-field="settings:1:heroHeadline">{settings.heroHeadline}</h1>3. Mount the client
Section titled “3. Mount the client”It self-gates: if the page has no markers (that is, it wasn’t rendered in edit
mode) mountLouise() does nothing—so published pages ship no editor JS.
import { mountLouise } from "louise-toolkit/client";mountLouise();4. Accept the save
Section titled “4. Accept the save”The client sends one PATCH per changed field to your editor route. Louise’s
saveRoute builds that route for you—you pass your own table, an allowlist
of writable fields, and a resolveEditor that decides who may edit.
// src/pages/api/louise/[...path].ts — mounted at /api/louise/*import { saveRoute, runEditorRoute } from "louise-toolkit/editor";import { siteSettings } from "../../../schema"; // your Drizzle table
const route = saveRoute({ // Placeholder gate — returns an editor or null. Swap for real auth (step 5). resolveEditor: (request) => (isEditor(request) ? { id: "you" } : null), collections: { settings: { table: siteSettings, fields: ["heroHeadline"] }, // allowlist! },});
export const ALL = (ctx) => runEditorRoute(route, ctx.request, ctx.locals.runtime.env);Only allowlisted fields are writable—a forged request can never touch an unlisted column.
5. Gate it with real auth
Section titled “5. Gate it with real auth”Step 4 used a placeholder resolveEditor. In production, resolve a real editor
session—Louise ships a better-auth integration and a same-origin/CSRF guard.
See Auth & edit mode for the session flow that
turns a viewer into an in-place editor, and marks the page for edit mode so
mountLouise() activates.
Next steps
Section titled “Next steps”- Getting started—the full mental model
(dependency-injected primitives,
astro:env, the field lifecycle). - Core concepts—collections, sections, drafts, settings.
- Is Louise for you?—honest comparison vs. Tina / Sanity / Payload, and the explicit non-goals.
- Then reach for the primitive you need: Forms, Media, Commerce, AI assists, and the full reference.