Live Preview
The admin’s Live Preview button opens your frontend with a preview_token query parameter. The token is signed, scoped to one entry (or one page), and expires after 15 minutes. Without a valid token the normal public API still returns 404 for drafts.
1. Configure the preview URL
Section titled “1. Configure the preview URL”In the CMS, set the templates under Settings → API:
- Entry template: must contain
{slug}, and may use{contentType}. For examplehttps://your-site.com/blog/{slug}. - Page template: must contain
{route}.
2. Bind a client per request
Section titled “2. Bind a client per request”import { defineMiddleware } from 'astro:middleware';import { createKenresoftClient, getPreviewToken } from '@kenresoft-cms/astro';
export const onRequest = defineMiddleware((context, next) => { context.locals.cms = createKenresoftClient({ url: import.meta.env.PUBLIC_KENRESOFT_CMS_URL, previewToken: getPreviewToken(context.url), }); return next();});3. Use it in pages
Section titled “3. Use it in pages”---const post = await Astro.locals.cms.entries.get({ contentType: 'blog-post', slug });---entries.get() and pages.resolve() on that client use the token automatically. On a normal request getPreviewToken returns null and nothing changes. Pass previewToken: null on a call to force published-only rendering. An explicit previewToken on a call overrides the client default. Without middleware, pass the token per call: entries.get({ contentType, slug, previewToken: getPreviewToken(Astro.url) }).
The new-site starter includes this middleware.
Requirements
Section titled “Requirements”- The page must render on demand. Under
output: 'static'withgetStaticPaths(), a draft’s slug was never built, so Astro returns404before your code runs. Useoutput: 'server', or addexport const prerender = false;to just that page (needs an adapter). - Save first. Live Preview shows the saved entry, not unsaved edits.
- Pages: a preview link goes to a route that is not in the published
pages.list(). Check for a token first and callpages.resolve({ route })directly, as the example site’s catch-all does. See Rendering pages. - Commerce product pages have no preview token: products are not entries.
If a draft still returns 404 on an on-demand page, check the token has not expired (15 minutes), that the URL matches the button’s exactly, and that the request actually reaches the client you think it does.