Documentation Index
Fetch the complete documentation index at: https://docs.avocadostudio.dev/llms.txt
Use this file to discover all available pages before exploring further.
Deploy to Vercel
This guide covers deploying Avocado Studio to Vercel.Overview
The recommended deployment splits across two platforms:- Site + Content Studio on Vercel (static/serverless hosting)
- Orchestrator on a long-running host (Render, Fly.io, Railway, or any container platform)
Required now (Phase 1)
apps/sitemust render published content without requiring orchestrator at runtime.- Add production fallback so site never fails to render if orchestrator is unavailable.
- Disable or protect
__editor=1in production. - Deploy only
apps/siteas a single Vercel project.
Current architecture (from this repo)
apps/siteis a Next.js app.apps/orchestratoris a Fastify API with in-memory state + file persistence (.data/orchestrator-state.json).apps/editoris a Vite app that currently hard-codes local URLs.- The site currently reads draft content from
ORCHESTRATOR_URL(/draft/pages,/draft/slugs).
Important decision first
Pick one deployment target:- Public website only (recommended for launch)
- Full Content Studio + orchestration stack on Vercel
1) Public website only (recommended)
Use this if you want a stable public site and do not need live editing in production.Required changes
- Decouple
apps/sitefrom draft API at runtime.
- Today,
apps/sitefetches draft pages from orchestrator. - For production, render from a published source (shared seed content, JSON, CMS, or database).
- Keep orchestrator integration optional (for dev/editor mode only).
- Add a published content source for site rendering.
- Option A: Use
demoPublishedPages()frompackages/sharedas initial published content. - Option B: Load from a real storage backend (recommended long term).
- Add production fallback behavior.
- If orchestrator is unavailable, site should still render published pages (not
Page not found).
- Restrict or disable editor mode in production.
__editor=1should be disabled or protected.- Avoid exposing editor bridge behavior publicly by default.
Vercel config
Create one Vercel project forapps/site:
- Root Directory:
apps/site - Install Command:
pnpm install --frozen-lockfile - Build Command:
pnpm --filter @ai-site-editor/site build - Output: Next.js default
Environment variables (site)
ORCHESTRATOR_URL(optional in public-only mode; required only if you keep remote draft fetches)NEXT_PUBLIC_EDITOR_ORIGIN(optional; only if editor mode is enabled)
2) Full Content Studio stack on Vercel (site + orchestrator + Content Studio)
Use this only if you want production Content Studio workflows.Required code changes
- Remove hard-coded local origins from
apps/editor/src/App.tsx.
- Replace:
editorOrigin = "http://localhost:4100"siteOrigin = "http://localhost:3000"orchestrator = "http://localhost:4200"
- With Vite env vars (
import.meta.env.VITE_*).
- Remove hard-coded local defaults in
apps/site.
DEFAULT_EDITOR_ORIGINshould come from env (NEXT_PUBLIC_EDITOR_ORIGIN) instead ofhttp://localhost:4100.- Keep
ORCHESTRATOR_URLrequired for editor-enabled production.
- Rework orchestrator persistence.
- Current implementation relies on in-memory Maps + filesystem persistence.
- Vercel functions are ephemeral; local file persistence is not durable.
- Move state to durable storage (Postgres, Redis/KV, etc.).
- Rework orchestrator runtime model for Vercel.
- Current API starts a standalone server via
app.listen(...). - For Vercel, expose request handlers/functions instead of long-running process assumptions.
- Tighten CORS in orchestrator.
- Current CORS is
origin: true(too open for production). - Restrict to known site/Content Studio origins via env-based allowlist.
- Review streaming endpoint behavior (
/chat/stream).
- Ensure it fits your Vercel function execution limits and plan.
- Add fallback to non-streaming
/chatif needed.
Vercel projects
Set up separate projects:siteproject (Next.js)
- Root:
apps/site - Env:
ORCHESTRATOR_URL,NEXT_PUBLIC_EDITOR_ORIGIN(if used)
orchestratorproject (API)
- Root:
apps/orchestrator - Env:
OPENAI_API_KEY, model env vars, storage connection env vars, CORS allowlist
- Content Studio project (optional)
- Root:
apps/editor - Env:
VITE_EDITOR_ORIGIN,VITE_SITE_ORIGIN,VITE_ORCHESTRATOR_URL
Minimal change list before first Vercel publish
If the goal is to publish quickly, do these first:- Implement published rendering path in
apps/sitethat does not require orchestrator. - Disable/protect production Content Studio mode.
- Deploy
apps/siteonly on Vercel.
Deferred (Phase 2, later)
- Deploy
apps/orchestratoron Vercel-compatible runtime. - Move orchestrator state to durable external storage.
- Migrate Content Studio/site/orchestrator origins to env-only configuration.
- Lock CORS to explicit allowlist.
- Deploy
apps/editor(if production editing is required).
Suggested rollout plan
- Phase 1: Public site only on Vercel (stable, low risk)
- Phase 2: Externalize orchestrator state storage
- Phase 3: Deploy orchestrator + Content Studio with locked CORS and env-driven origins
Recommended Beta Split (Avoid Production Overwrite)
Use separate URLs/environments for production and Content Studio staging.Production site (stable)
- Vercel project/branch:
main - URL: public production URL (for end users)
- Env:
ORCHESTRATOR_URLunsetNEXT_PUBLIC_ENABLE_EDITOR=0
apps/site/lib/published-content.json only.
Staging site (Content Studio preview target)
- Vercel project or branch:
beta-editor(recommended separate project URL) - URL: staging URL
- Env:
ORCHESTRATOR_URL=https://<orchestrator-host>NEXT_PUBLIC_ENABLE_EDITOR=1NEXT_PUBLIC_EDITOR_ORIGIN=https://<editor-host>
Content Studio app
- Vercel project root:
apps/editor - Env:
VITE_SITE_ORIGIN=https://<staging-site-host>(not production)VITE_ORCHESTRATOR_URL=https://<orchestrator-host>VITE_PUBLISH_TOKEN=<same as orchestrator PUBLISH_TOKEN>(if enabled)
Orchestrator
- Host on Render (or equivalent long-running host)
- Env:
PUBLISH_GIT_BRANCH=beta-editorORCHESTRATOR_CORS_ORIGINS=https://<staging-site-host>,https://<editor-host>
main.
Production troubleshooting
Block selector / overlay not working
The block selector requires a working postMessage channel between Content Studio iframe and site. Check these in order:-
Draft mode not enabled — without
VITE_SITE_DRAFT_SECRETon the Content Studio, the iframe URL uses__editor=1which is ignored in production. SetVITE_SITE_DRAFT_SECRETon the Content Studio andDRAFT_MODE_SECRETon site (matching values). -
NEXT_PUBLIC_ENABLE_EDITORnot set — the site’seditorModeisfalsein production unlessNEXT_PUBLIC_ENABLE_EDITOR=1is set. Without it,PreviewBridgenever mounts and blocks have no click handlers. -
Origin mismatch in postMessage —
event.originnever has a trailing slash. IfNEXT_PUBLIC_EDITOR_ORIGINorVITE_SITE_ORIGINhas a trailing slash, all messages are silently dropped. Always omit trailing slashes. -
Missing
/api/editor/pages— the Content Studio calls this on the site to seed the orchestrator with initial content. Without it, the orchestrator has no draft pages and the site shows “Draft unavailable”. -
CORS on orchestrator —
ORCHESTRATOR_CORS_ORIGINSmust include both the Content Studio and site origins.
Required env vars (full stack)
| Component | Variable | Notes |
|---|---|---|
| Orchestrator | OPENAI_API_KEY | or ANTHROPIC_API_KEY |
ORCHESTRATOR_PUBLIC_ORIGIN | its own public URL | |
ORCHESTRATOR_CORS_ORIGINS | comma-separated Content Studio + site origins | |
| Site | ORCHESTRATOR_URL | orchestrator public URL |
NEXT_PUBLIC_ENABLE_EDITOR=1 | enables editor mode | |
NEXT_PUBLIC_EDITOR_ORIGIN | Content Studio URL, no trailing slash | |
DRAFT_MODE_SECRET | shared secret with Content Studio | |
| Content Studio | VITE_SITE_ORIGIN | site URL, no trailing slash |
VITE_SITE_DRAFT_SECRET | must match site DRAFT_MODE_SECRET | |
VITE_ORCHESTRATOR_URL | orchestrator public URL |
Orchestrator on Render
The orchestrator runs viatsx src/index.ts (not compiled JS). tsx is a production dependency. The build step is tsc --noEmit (typecheck only). Render build command: pnpm install --frozen-lockfile && pnpm --filter @ai-site-editor/orchestrator build.