Deviopath › Next.js

Draft Mode Preview Route

Hard · Route Handlers

Draft Mode lets editors preview unpublished CMS content on a statically generated site. The CMS opens a URL like /api/draft?secret=...&slug=/posts/hello-world; your route handler checks the secret, calls (await draftMode()).enable() (which sets the __prerender_bypass cookie) and redirects to the post. On the next requests Next.js skips its caches for that editor, and pages read draft content.

The starter has a simplified draftMode() (it records enable() instead of setting a cookie) and a fake CMS whose getPostBySlug(slug) accepts messy input like Hello-World or /posts/hello-world/.

Write GET(request):

- Read secret and slug from new URL(request.url).searchParams.

- Wrong or missing secret: 401 with the text Invalid token. Missing slug: 400 with Missing slug. The CMS does not know the slug: 404 with Unknown slug. Draft mode must stay disabled in all these cases.

- Otherwise enable draft mode and redirect with status 307 to the post's path from the CMS, never to the raw slug parameter: otherwise a crafted link (slug=//evil.test) could send the editor to another site (an open redirect). Build an absolute URL with new URL(post.path, request.url) and return Response.redirect(url, 307). (In a real app you would call redirect(post.path) from next/navigation, which also answers with a 307.)

Also write getPost(path, isDraft) for the page: when isDraft is true and the post has a draft, return the draft content with preview: true; otherwise the published content with preview: false; null when there is nothing to show (unknown post, or never published outside draft mode).

Next: App Router URL Resolver