Content Flow & Live Preview
Sources:
omni-cms-composable-cms/schemaTypes/lib/presentation/resolve.ts,omni-web-content-frontend/src/app/api/draft-mode/
Published Content (Production)
Section titled “Published Content (Production)”Draft Content (Live Preview)
Section titled “Draft Content (Live Preview)”Presentation Tool Configuration
Section titled “Presentation Tool Configuration”Configured in sanity.config.ts:
presentationTool({ resolve: resolve, previewUrl: { initial: previewOriginNl, previewMode: { enable: "/api/draft-mode/enable", disable: "/api/draft-mode/disable", }, }, allowOrigins: [previewOriginNl, previewOriginCom].filter(Boolean),}),Preview Origins
Section titled “Preview Origins”| Variable | Domain | Countries |
|---|---|---|
SANITY_STUDIO_PREVIEW_ORIGIN_NL | .nl | Netherlands |
SANITY_STUDIO_PREVIEW_ORIGIN_COM | .com | Belgium, France, Germany |
URL Resolution
Section titled “URL Resolution”The resolve.ts function maps Sanity documents to frontend URLs:
| Country | Example URL |
|---|---|
| NL | https://preview.hema.nl/kerst-inspiratie |
| BE (Dutch) | https://preview.hema.com/nl-be/kerst-inspiratie |
| FR | https://preview.hema.com/fr-fr/noel-inspiration |
| DE | https://preview.hema.com/de-de/weihnachts-inspiration |
nl-nl is the default locale (no prefix in the URL path).
Draft Mode API Routes
Section titled “Draft Mode API Routes”Enable
Section titled “Enable”GET /api/draft-mode/enable?sanity-preview-secret=<secret>&sanity-preview-perspective=<perspective>- Validates the preview secret via
@sanity/preview-url-secret - Enables Next.js
draftMode() - Optionally sets perspective cookie (for Sanity Releases)
- Redirects to the target page
Disable
Section titled “Disable”GET /api/draft-mode/disableClears the draft mode cookie and redirects back.
Sanity Releases Support
Section titled “Sanity Releases Support”Draft mode supports Sanity Releases — scheduling content bundles. When a perspective cookie is set, the MFE fetches content from that specific release perspective.
async function isPreviewPerspectiveValid(perspective: string) { const releases = await clientWithToken.fetch("releases::all()[state == 'active']{name}"); return perspectiveIds.every(id => id === 'drafts' || releaseIds.includes(id));}Visual Editing (Stega)
Section titled “Visual Editing (Stega)”When draft mode is active, the client embeds invisible metadata in rendered strings. The Presentation Tool uses this to enable click-to-edit — clicking text in the preview opens the corresponding field in Studio.
Request Tagging
Section titled “Request Tagging”All Sanity requests are tagged for observability:
requestTagPrefix: "omni-web-content"// Draft requests get: "omni-web-content.draft"Implementing Draft Mode in a New MFE
Section titled “Implementing Draft Mode in a New MFE”- Add API routes:
src/app/api/draft-mode/enable/route.tsanddisable/route.ts - Configure Sanity client with
defineLive - Use
sanityFetchin your data layer (handles draft/published automatically) - Register your MFE’s preview URL in the CMS
sanity.config.ts:- Add origin to
allowOrigins - Add URL resolution rules in
resolve.ts
- Add origin to
- Set env vars:
SANITY_API_READ_TOKEN,NEXT_PUBLIC_SANITY_STUDIO_URL