BackmatterPricingDocs
Contents

Live preview

Unsaved edits on the real page, without rebuilding the site.

Preview shows your working tree on the real site. Visitors still see the published files. The page you are editing updates from the document in the editor. Everything else updates only when that document changes.

Open a document in the CMS and start preview, or browse the site with the dev bar. Both use this path.

Published and preview

PathWhoWhat it reads
PublishedVisitorsThe committed files, from cache. This path does not open draft mode and does not call the CMS.
PreviewYou, with a checkoutThe branch, with your working tree laid on top.

A commit invalidates the documents in that commit. The rest of the site stays cached. Changing one page does not rebuild every URL.

The document you are editing

The editor already holds the document. It sends that frontmatter and body to the page in the browser. The page re-renders with the same blocks and MDX the site uses. That keystroke does not ask the CMS for the document again.

The save still happens. Autosave writes the working tree on the same path as the dashboard. The picture on screen does not wait for that write.

If the render fails (a block is missing a required field, MDX does not parse), the page keeps the last good render and the editor hears the error.

While an editor is attached, the page applies those messages and ignores the stream for that document. The stream is still used when the document is deleted.

When no editor is attached

A preview opened on its own has no editor in the browser. The page listens to a per-document stream (EventSource on your origin, forwarded to the CMS). A save, including one from the agent, arrives as a change event and the page renders that document.

The stream is one document. It is not a feed of the whole tree.

Other documents on the page

A menu, an index, or a block that lists other documents reads the branch with your working tree on top. That overlay is cached for a few seconds against the version of your tree. A save or a commit drops the cache.

The open page also holds one tree stream. It says which document was added, edited, or removed, and when the branch head moves. The page refreshes when the event is for something it is showing. It does not download the tree.

A new document shows up. A deleted one disappears. A page built from other documents updates when one of those documents changes, by refreshing that page, not by replaying every keystroke of the other document.

Session

The browser never sees the workspace preview token. Entering preview sets an HttpOnly cookie, backmatter_preview_session, scoped to you, the workspace, the branch, and your tree. It lasts 12 hours. Logging out of the CMS ends it. The same cookie signs in the Studio mounted on the site.

The site calls its own origin. Route handlers attach the session and forward an allow-list to the CMS. Set the token on the server that serves the site:

BACKMATTER_PREVIEW_TOKEN=…

backmatter init adds app/api/backmatter/preview/route.ts. The same-origin CMS proxy is app/api/backmatter/cms/[...path]/route.ts:

import { createCmsProxy } from "@backmatter/next/cms-proxy";
import { cms } from "../../../../../.backmatter";

export const { GET, POST, PUT, DELETE } = createCmsProxy(cms);

The workspace's site URL must be this site. The ticket redirects to the public path of the document. You do not add a /preview route.

On a page you wrote

The catch-all from Next.js does this. A page you wrote yourself uses the same helpers:

import { fetchPreviewDoc, subscribePreview } from "@backmatter/next/preview";

fetchPreviewDoc loads the unsaved document for the first paint. subscribePreview applies it again when the working tree is saved and no editor is pushing the document. Both take the same workspace settings as cms (apiUrl, workspaceId) and BACKMATTER_PREVIEW_TOKEN.

Use the content token for published pages. Use the preview token only here.

Where you see it

SurfaceWhat drives the open document
CMS editor, site in an iframeThe editor sends the document into the iframe
Preview opened on its ownThe per-document stream
Dev bar on the siteThe site's own Studio editor, framed in the bar, sends the document to the page around it
Agent, while an editor is openThe editor reloads and sends the saved document
Agent, preview with no editorThe per-document stream