The default integration path usesDocumentation Index
Fetch the complete documentation index at: https://avocadostudioai.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
createEditorApiHandler and createSitePage — both of which import from next/headers and next/server. If your site is on Astro, Remix, SvelteKit, Hono, Cloudflare Workers, or any other framework that gives you web-standard Request and Response objects, you can implement the same contract by hand using the SDK’s framework-agnostic /core primitives instead. Same /api/editor/* URL paths, same wire format, same end state — your site appears in the editor’s dashboard, edits round-trip through Draft Mode (or the framework’s equivalent), and the rest of the docs apply.
Next.js is the only officially tested framework today. The
/core primitives below are framework-agnostic by design, but the only adapters shipped in the box are the Next.js ones in @ai-site-editor/site-sdk/draft and @ai-site-editor/site-sdk/routes. On any other framework you’ll be a first mover. The patterns on this page are real and the primitives work, but expect to file bugs and contribute back as you discover gaps.If you need an officially supported path on day one, the simplest option is to wrap your app in a thin Next.js shell that proxies to your existing backend, and use the standard Next.js Integration. That’s not what most readers of this page want to hear, but it’s the truth.What you have to implement
The contract the editor speaks is five HTTP routes mounted under/api/editor/*. On Next.js the SDK’s catch-all handler implements all five for you. Off Next.js, you implement them yourself, but the SDK gives you most of the logic via the /core exports — you only have to provide a small adapter that translates between your framework’s request/cookie/redirect primitives and the SDK’s web-standard ones.
| Route | Purpose | SDK helper to call |
|---|---|---|
GET /api/editor/blocks | Block manifest (auto-built from the SDK’s built-in registry, override with your own) | createBlocksHandler |
GET /api/editor/pages | { pages: PageDoc[] } of published content for editor session bootstrap | createPagesHandler |
GET /api/editor/draft?secret=...&redirect=... | Draft Mode entry — validates secret, sets cookies, redirects | createDraftEnableHandlerCore |
GET /api/editor/draft/disable?redirect=... | Draft Mode exit — clears cookies, redirects | createDraftDisableHandlerCore |
POST /api/editor/publish | Receives published pages back from the editor (only if you support publish) | createPublishHandler |
1. Blocks and pages (no adapter needed)
createBlocksHandler, createPagesHandler, and createPublishHandler already accept and return web-standard Request and Response objects. They have no Next.js dependency — you can mount them on any framework that lets you wire a (request: Request) => Response handler to a route.
Astro example
[...path].ts catch-all for a cleaner version — this is the verbose form to make the wiring obvious.)
Hono / Cloudflare Workers example
2. Draft Mode routes (needs an adapter)
The Draft Mode entry / exit routes need to do three framework-specific things:- Toggle draft mode — on Next.js this is
(await draftMode()).enable(). On other frameworks, draft mode is usually a cookie you set; there’s no global “enable” function. The SDK callsenableDraftMode()on your adapter; you decide what that means. - Set cookies on the response — every framework handles this differently. The SDK passes a list of cookies to your adapter; you attach them to whatever response object you return.
- Build the redirect response — same idea. The SDK gives you the destination
URLand the cookies; you return a framework-appropriateResponse.
SvelteKit example
What enableDraftMode actually means off Next.js
Next.js has a global draftMode() API that flips a server-side flag, and next/headers reads it back from inside your page render. No other framework has this. On every other framework, the closest equivalent is “set a cookie that your page-render code checks.”
The __draft_enabled=1 cookie in the SvelteKit example above is illustrative — pick whatever name and shape works for your stack. The SDK doesn’t care what your draft flag looks like; it only cares that:
- The
/api/editor/draftroute validates the secret and sets it - The
/api/editor/draft/disableroute clears it - Your page render code reads it and switches between published and draft data sources
enableDraftMode / disableDraftMode adapter callbacks are usually no-ops on non-Next.js frameworks — the createRedirect callback does the real work by attaching the cookie.
3. Page render: switching between published and draft
This is the part that lives outside the editor API routes. When a user visits/pricing on your site:
- Published mode (no draft cookie): your page handler reads from your CMS / file system / database and renders normally.
- Draft mode (your draft cookie is set, OR
?session=…&siteId=…query params from the editor iframe): your page handler reads from the orchestrator’s/draft/pagesendpoint instead, and shows the editor overlay.
Helper A: fetchEditorPage and fetchEditorSlugs (no adapter needed)
These are plain fetch() wrappers around the orchestrator’s draft endpoints. Use them anywhere you can call await fetch():
{ orchestratorUrl } override if you don’t want to set the env var.
Helper B: resolveDraftContextCore (needs an adapter)
This is the helper that figures out whether you’re in draft mode by looking at cookies, query params, and env defaults — the same logic createSitePage uses internally on Next.js. It needs a tiny adapter so it can read your framework’s cookies:
null (you’re in published mode) or { session, siteId, editorOrigin } (you’re in draft mode and should call fetchEditorPage with these values).
Putting it together (SvelteKit pseudo-code)
4. Register the site
This step is framework-independent. From your project directory, run the same registration CLI that the Next.js path uses:DRAFT_MODE_SECRET, ORCHESTRATOR_URL, NEXT_PUBLIC_DEFAULT_SITE_ID, NEXT_PUBLIC_SITE_NAME, NEXT_PUBLIC_EDITOR_ORIGIN to your .env.local. The NEXT_PUBLIC_* variable names are vestigial from the Next.js convention — your framework will read them just fine, or you can rename them on the way in (the SDK doesn’t actually require those specific names; only DRAFT_MODE_SECRET is non-negotiable).
After it succeeds, the site appears in the editor’s dashboard the next time you open or refresh http://localhost:4100.
5. Verify the contract
Samecurl checks as the Next.js walkthrough — the contract is identical regardless of which framework implements it. See the Verify the contract step for the five curl commands that should all pass against your routes.
What you don’t get on the non-Next.js path
The Next.jscreateSitePage helper does several things automatically that you’ll have to do by hand:
What createSitePage does | What you’ll do instead |
|---|---|
Branches between draft and published reads via next/headers | Branch on your own getDraftContext (section 3 above) |
| Renders the SDK’s built-in block library out of the box | Import renderBlocks from @ai-site-editor/site-sdk and call it yourself, OR use your own block renderer that maps block.type strings to your components |
Mounts the live EditorOverlay for in-iframe editing | Import EditorOverlay from @ai-site-editor/site-sdk/editor and mount it conditionally when in draft mode |
Builds the site header / nav / footer chrome from getSiteConfig | Build your own — or just import buildNavItems and buildSiteHeaderBlock from @ai-site-editor/site-sdk/navigation |
Generates generateStaticParams from getSlugs | Implement your framework’s equivalent (Astro getStaticPaths, Remix loaders + dynamic rendering, etc.) |
packages/site-sdk/src/create-site-page.tsx is the reference implementation; on a non-Next.js framework, you’re translating it into your framework’s idioms.
Compared to the alternatives
If this looks like a lot of work, here are your other options:- Wrap your app in a thin Next.js shell that proxies to your existing backend. Use the standard Next.js Integration. Most people who try the non-Next.js path end up here anyway. ~30 minutes of work, fully supported.
- Use the Bring Your Own Coding Agent workflow to have your IDE agent (Codex / Cursor / Claude Code) do the wiring for you, on your framework. The prompt template still assumes Next.js but the agent can usually adapt; results vary.
- File a feature request for an official adapter for your framework. If we see repeated requests for Astro / Remix / SvelteKit, those become candidates for first-class support and stop being “first mover” territory.
Filing bugs and contributing
The/core exports are real and tested (the Next.js shims in the SDK use them as their own implementation), but the patterns on this page are illustrative — they haven’t been verified against every framework’s quirks. If you hit something:
- Open an issue at github.com/yu7321/avocado with the framework, the version, and the exact symptom
- If you build a working adapter for a popular framework, please contribute it back as
@ai-site-editor/site-sdk/draft-routes-{framework}.ts— that’s how Astro / Remix / SvelteKit move from “first mover territory” to “officially supported” - The Next.js adapter at
packages/site-sdk/src/draft-routes.tsis 30 lines and is the reference for what a framework adapter looks like