Alinea’s preview system embeds your application in an iframe inside the dashboard so editors can see content changes in real time before they publish. When an editor opens the preview, Alinea signs a JWT preview token and redirects the iframe to your site via the handler’s preview redirect endpoint, which enables Next.js Draft Mode and sets the token as a cookie. From that point on, every edit the editor makes is pushed to the page as a live patch without requiring a full reload.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/alineacms/alinea/llms.txt
Use this file to discover all available pages before exploring further.
Enabling previews in config
Setpreview: true in your CMS config to activate the preview feature:
src/cms.ts
preview option accepts:
Set to
true to enable previews using the default URL strategy derived from
baseUrl. Set to a React component to provide a fully custom preview
renderer that receives the live entry object as a prop.Rendering the preview widget
Add the floating preview widget to your root layout so it appears when an editor opens a page in the dashboard iframe. Callcms.previews() — it returns null when Draft Mode is disabled, so the widget is invisible to regular site visitors:
app/layout.tsx
cms.previews() accepts a PreviewProps object:
When
true, renders the floating <alinea-preview> widget that shows
connection status and provides a direct link back to the entry being edited
in the dashboard. When false or omitted, the hook still subscribes to live
patches but does not render any visible UI.The workspace key to use when constructing the “edit this entry” link in the
widget. Omit to use the default workspace.
The root key to use when constructing the “edit this entry” link. Omit to
use the default root.
cms.previews() is an async server component helper. It reads the Next.js draftMode() and cookies() headers to determine whether Draft Mode is active. The <NextPreviews> component it returns is loaded with next/dynamic and ssr: false so it only runs in the browser — the widget registers itself with registerPreviewWidget() and listens for patch messages from the dashboard iframe.
How the preview handshake works
- The editor clicks Preview in the dashboard.
- Alinea creates a signed JWT containing the target URL and opens your app in an iframe at
GET /api/cms?preview=<token>. - The handler verifies the token, calls
draftMode().enable(), and issues a302redirect to the target URL. - The page re-renders in Draft Mode.
cms.resolve()detects the draft mode cookie and switches topreferDraftstatus so unpublished edits are included. - The
<alinea-preview>widget establishes apostMessagechannel with the parent dashboard frame. - Each subsequent edit in the dashboard sends a patch via
postMessage. The widget applies it viasetPreviewCookies()and triggersrouter.refresh()to re-render the server components with the updated content.
Draft workflow with enableDrafts
When enableDrafts: true is set in your config, every content change goes through a draft state before it can be published:
src/cms.ts
baseUrl and preview routing
baseUrl tells Alinea where your application is hosted so it can construct preview redirect URLs. You can provide a single string or split development and production URLs:
src/cms.ts
baseUrl is required in production. Without it, requestContext throws at runtime because it cannot construct the handler URL used for preview redirects and API calls.
Preview status in the widget
The<alinea-preview> widget reflects the current connection state via the livePreview attribute:
| State | Meaning |
|---|---|
"connected" | Live patching is active |
"loading" | A patch is being applied and the router is refreshing |
"warning" | Patch was received but setPreviewCookies failed (usually a cross-origin cookie restriction) |
undefined | Draft Mode is enabled but no patch has arrived yet |