Skip to content
decodecodeveloper docs
Storefront → Blocks → Core concepts

Site Editor and the v7 admin protocol

The v7 runtime's metadata, preview, invoke and content reload endpoints, and how they relate to Studio's repository-backed Site Editor.

Current Site Editor workflow. Studio saves repository-backed content edits to a working branch. Publish pushes and synchronizes that branch, opens or updates a pull request, and squash-merges it; Request review leaves the PR unmerged. The deployment integration applies the merged content. The runtime POST /.decofile endpoint below is a separate v7 capability for clients and delivery integrations, not the current Studio Publish action. See connecting a site and publishing changes.

The Site Editor is the storefront editing app hosted by Deco Studio. It uses the site's metadata and preview endpoints alongside repository-backed content editing. The 7.x runtime also exposes a small set of HTTP endpoints, called the admin protocol, for compatible clients to read schemas and content, render previews, invoke loaders and reload content. This page lists those endpoints, shows how each binding mounts them, and covers the settings that affect what editors see.

Site Editor
The storefront editing app in Studio. It combines site metadata and previews with repository-backed content edits and a GitHub publish workflow. See the glossary.
Admin protocol
The v7 site's HTTP contract for compatible editor and delivery clients. See the glossary.
Render shell
The HTML document previews render inside: your stylesheet, fonts and theme.

The v7 runtime contract

Schema
GET /live/_meta: which sections and loaders exist and what their forms look like
Content
GET /.decofile: the current blocks
Preview
/live/previews/*: a section or page rendered with the editor's unsaved props
Runtime reload
POST /.decofile: the new content, applied in memory

Editor clients can load the site in an iframe and call these endpoints from a browser, so the handlers include CORS headers. Current Studio content saving and publishing follow the repository workflow described above; mounting these handlers does not connect a repository or configure deployment. All the handlers come from @decocms/blocks-admin; the bindings mount them for you.

The endpoints

Method and pathWhat it does
GET /live/_metaReturns the schema (.deco/meta.gen.json, composed with the framework's types) with an ETag. Answers 304 when Studio's If-None-Match matches, 503 when no schema is configured. Also served at /deco/meta.
GET /.decofileReturns the current decofile, with the revision as ETag and Cache-Control: no-cache.
POST /.decofileReplaces content. See Publishing.
GET /live/previewsThe empty HTML shell Studio's preview frame starts from.
GET or POST /live/previews/<block or section>Renders one section, a saved block, or a whole page (website/pages/Page.tsx) with the props Studio sends, inside the render shell.
POST /deco/renderThe same renderer, with the component given in the body or the resolveChain query parameter.
POST /deco/invoke/<key>, POST /deco/invokeCalls a loader or action by key, or a batch of them. See Loaders and actions.
GET /deco/_livenessAnswers OK, for health checks.

Page previews evaluate matchers against the path and device Studio is previewing (?path=, ?deviceHint=mobile), and run section loaders, so the preview shows real data. Each previewed section is wrapped in a <section data-manifest-key="…"> so Studio can map clicks back to blocks. Errors render inline in the preview rather than failing the request.

Publishing

An authorized runtime client can reload content with POST /.decofile. This endpoint does not commit content to Git or run Studio's Publish workflow. Its body is one of two shapes:

  • A delta: an object whose only key is blocks, holding the changed blocks. A null value deletes that block.

    A delta publish
    { "blocks": { "Header": { "__resolveType": "site/sections/Header/Header.tsx", "logo": "https://www.example.com/logo-v2.svg" }, "pages-old-sale": null } }
  • A full decofile: any other object replaces all content.

The site applies it with setBlocks, clears its loader cache, invalidates the schema ETag, and, with Fast Deploy, writes the snapshot to KV. It answers:

FieldMeaning
oktrue
mode"delta" or "full"
previousBlockCount, newBlockCountBlock counts before and after
revisionThe new content revision
kvWrittenWhether the snapshot was written to KV (always false without Fast Deploy)
timestampWhen it was applied

Outside development, this runtime reload endpoint requires a token. Set DECO_RELEASE_RELOAD_TOKEN in the site's environment, and the request's Authorization header must equal it exactly. Without the variable, every runtime reload request is refused with 401. In development (NODE_ENV=development) no token is needed, which is how the TanStack dev server applies your local block edits.

In TanStack Start

The endpoints are split between the Worker entry and three file routes.

createDecoWorkerEntry handles /live/_meta, /.decofile, /live/previews and /live/previews/*, and /deco/_liveness, when you pass the handlers as its admin option. These responses are never cached.

src/worker-entry.ts (excerpt)
import {
  corsHeaders,
  handleDecofileRead,
  handleDecofileReload,
  handleMeta,
  handleRender,
} from "@decocms/blocks-admin";
 
export default createDecoWorkerEntry(serverEntry, {
  admin: { handleMeta, handleDecofileRead, handleDecofileReload, handleRender, corsHeaders },
});

The file routes src/routes/deco/meta.ts, src/routes/deco/invoke.$.ts and src/routes/deco/render.ts serve the rest, using decoMetaRouteConfig(), decoInvokeRouteConfig() and decoRenderRouteConfig(). Call each factory in its own route file. The quickstart has all three.

Mount the admin handlers in createDecoWorkerEntry, not in TanStack's createServerEntry. Production builds drop custom request handling from the server entry, so the endpoints work in development and then return your HTML page in production. If /live/_meta returns HTML, check this first, and check that wrangler.jsonc's main points at src/worker-entry.ts.

In Next.js

One catch-all route, app/deco/[[...deco]]/route.ts with createDecoRouteHandlers({ setup }), serves every endpoint. withDeco in next.config rewrites the public paths onto it, because Next.js route folders can't start with a dot:

Public pathRewritten to
/.decofile/deco/decofile
/live/_meta/deco/meta
/live/previews/:path*/deco/previews/:path*

Preview GETs redirect to the fixed page /deco/preview, rendered by createDecoPreviewPage, so Client Components work in previews; see Previews and draft preview. On Next.js, /deco/meta accepts only GET and /deco/invoke only POST. The Next.js quickstart shows both files.

What previews look like

Previews render your sections outside your app's normal layout, so you tell the admin side what the surrounding document needs. On TanStack, createAdminSetup from @decocms/blocks-admin/setup takes:

OptionTypeWhat it does
meta() => Promise<schema>Loads the schema. Required. Keep it a dynamic import().
cssstringURL of your stylesheet (a Vite ?url import). Required.
fontsstring[]Font stylesheet URLs to load in previews.
previewWrappercomponentWraps every preview, to provide context your sections need. Use PreviewProviders from @decocms/tanstack.
getCommerceLoaders() => Record<string, loader>The loaders /deco/invoke can call, if you don't register them with setInvokeLoaders.

On Next.js, the same settings are createNextSetup's meta, renderShell: { css, fonts } and previewWrapper.

For anything else about the shell, call setRenderShell from @decocms/blocks-admin in setup. It takes css, fonts, theme (the data-theme attribute), bodyClass and lang. If your styles use DaisyUI color variables, set the theme, or previews render without colors:

src/setup.ts (excerpt)
import { setRenderShell } from "@decocms/blocks-admin";
 
setRenderShell({ theme: "light" });

The Next.js preview page already defaults the theme to light.

Live controls

DecoRootLayout (in both bindings) renders LiveControls, a small script that lets Studio and the page talk while the page is in Studio's frame: it reports which page is open and responds to editor messages. Outside Studio it also adds a shortcut: press . on your site to open it in Studio (Ctrl/⌘ + . for a new tab).

CORS and framing

Studio calls the admin endpoints from the browser, so they answer with CORS headers that allow GET, POST and OPTIONS and the Content-Type, Authorization and If-None-Match headers. On Next.js, OPTIONS preflights are answered without running setup.

Studio also shows your pages in a frame. On TanStack, HTML responses carry a frame-ancestors policy that lets Deco's Studio frame your pages; see TanStack Start on Cloudflare Workers to change the security headers.

Next steps

Current editor implementation reference: Studio publish flow. Reviewed 2026-10-05.