Three paths
Recommended
Your coding agent
Claude Code, Codex, Cursor — whatever you already run. It knows your codebase, your conventions and your history, and the work lands in your repo through your normal review flow. We give you the prompt and the number that says you are done. Every production integration has used this path.
Early
Built-in agent
An agent inside the editor that migrates a public URL, integrates a repo, or scaffolds a new site. Claude-only, and its first pass is a draft you will refine. Needs the standalone orchestrator; library mode does not mount it.
Reference
The contract
Every seam the integration must satisfy, whether a human or an agent writes the code. Read this if you want to understand the shape before you delegate it — or review what an agent produced.
Next.js is the tested path; Astro is a supported one. Avocado is built and tested against Next.js 15 and 16 (App Router) on Node 22+, and every production integration so far is Next.js. On Astro 5+, install
@avocadostudio-ai/astro instead — it mounts the editor routes and the preview bridge from one config block, with your own .astro components doing the rendering and no React added. It ships with examples/astro-site/ and two gates that drive that fixture on every push, one of them running the preview in a real browser. What neither covers is contact with a large real template, so expect gaps there and tell us when you find one. Before you deploy, read Production: three of the integration’s settings are inert in development, so nothing in your local loop can tell you they are wrong. Any other framework can be wired through the framework-agnostic /core primitives — see Non-Next.js integration — but you would be a first mover.What the work actually is
Three things, in this order. Nothing else about your site changes.1. Declare the content model
Your components become blocks by registering a schema that says which props are content and what kind each one is — text, richtext, image, link, list. That registration is the boundary: a prop you declare is editable, a prop you do not declare is not, and no amount of asking changes that. On a JSON- or file-backed site this isregisterBlock from @avocadostudio-ai/site-sdk/blocks. On a CMS-backed site it is a field table, which derives the Zod schema, the property-panel metadata, the projection out of the CMS and the merge back into it from one declaration instead of four that drift apart.
One-time, plus one line whenever someone needs a field that is not there yet.
2. Mark up the renderers
The editor addresses a field by a path scoped from the block down —items[3].question. Your components have to say which DOM element carries which path, using editableProps and, where a list row is drawn by a component of its own, editableScopeProps from @avocadostudio-ai/site-sdk/markers.
This is the part that takes the longest on a real design system, because it is a pass over every renderer. Skipping a field is silent: the block still renders, the panel still lists the prop, and clicking it on the page does nothing.
One-time, and then a habit — a new renderer needs its markers the way it needs its types.
3. Adapt the CMS
Two functions:getPages() returns your content as pages of blocks, onPublish(pages, config) writes edits back. How much sits behind them depends entirely on your CMS. A JSON-backed site is almost nothing. A CMS that localises per field and stores list rows as their own documents is the real work — see CMS adapters and multilingual.
Working examples ship in the repo under examples/sample-site/ (JSON), examples/astro-site/ (Astro, JSON written back under src/), examples/contentful-site/, examples/sanity-site/ and examples/strapi-site/. Field-table lens packs ship for Storyblok and Sanity.
One-time. Publishing after that is a field-level diff, so a page nobody touched writes nothing.
POST /api/editor/publish — the contract endpoint a standalone orchestrator
publishes into — is guarded twice, because it replaces the site’s content.
Under NODE_ENV=production it refuses every request until publishSecret is
configured; the scaffolds read that from PUBLISH_TOKEN, which the orchestrator
sends back as x-publish-token. And in any environment, a publish that would
remove every page is refused with a 409 unless the body carries
"allowDelete": true — what actually produces an empty page list is a client
publishing what it thinks it has after its own state failed to load, not someone
deleting a site. Removing one page of several stays an ordinary edit.
What recurs
Almost nothing. After the integration lands, adding a field is one line in the field table, adding a block is a registration plus markers, and everything else — the copy changes, the images, the sections, the metadata, the translations — is your marketing team talking to the site.Which path should you pick?
Path 1 — Hand it to your own coding agent
This is the path we recommend. Your agent already has what ours does not: your codebase, your conventions, your component library, your CMS client, and the history of why things are the way they are. Our agent has to discover all of that from scratch inside a repository it has never seen, and on a non-trivial site it discovers some of it wrong. What you get: a copy-paste prompt that sends the agent to the right doc pages, names the SDK surfaces it should use, and ends on a verification step that is a number rather than “the dev server started”. What you keep: your review flow. The agent opens a branch, you read the diff, CI runs, you merge. Nothing lands in your repo that you did not approve. → Hand it to your own coding agentPath 2 — The built-in onboarding agent
An agent inside the editor’s Sites page, with three modes:Claude only. The onboarding agent runs on Anthropic Claude — either through your Claude subscription via the CLI backend, or an
ANTHROPIC_API_KEY via the SDK backend. An OpenAI key alone will not drive this path. The editor’s per-edit chat, which is the AI you talk to after a site exists, runs on Anthropic, OpenAI or Google.Path 3 — Read the contract
Whoever writes the code, the integration has to satisfy the same contract: the five/api/editor/* endpoints, the page factory, the block registration, the markers, and the registration call. The contract page walks each seam and says what it is for.
Read it if you want to understand the shape before delegating, or to review what an agent produced. It is a reference, not a race.
→ The integration contract
How you know you are done
Not “it builds”. Not “the dev server started”. Two numbers:editableCoverage— of the fields your manifest declares, how many does a rendered page actually carry a marker for? A field that lost its marker in a refactor is a field marketing silently cannot click.panelCoverage— is the property panel intelligible? Can every list row be told apart, do polymorphic branches narrow, is anything in your content described by nothing?
@avocadostudio-ai/site-sdk/coverage and run without a browser or a model call. Put them in CI and the integration stops regressing.
→ Coverage checks
After your site is in
- A tour of the editor — what your team sees once the site is in
- Custom blocks — register more of your own components
- Field table — one declaration, four consumers
- Visual editor — enable click-and-drag editing alongside the AI chat editor
- Publishing — field-level diffs back into your CMS
- Deployment — run the orchestrator on your own infrastructure