Preview and drafts
Seeing unpublished content, and sharing it with people outside.
The preview handshake
The editor's Preview button opens {your site}/api/contentbind-preview?token=...&redirect=... - a route your app provides. It stores the short-lived token in a cookie and redirects to the page. Without it, Preview lands on a 404.
App Router:
// app/api/contentbind-preview/route.ts
import { NextResponse, type NextRequest } from 'next/server'
export function GET(request: NextRequest) {
const token = request.nextUrl.searchParams.get('token')
const redirect = request.nextUrl.searchParams.get('redirect') ?? '/'
if (!token) return NextResponse.json({ error: 'token required' }, { status: 400 })
const target = redirect.startsWith('/') ? redirect : '/'
const response = NextResponse.redirect(new URL(target, request.url), 303)
response.cookies.set('contentbind_preview', token, {
httpOnly: true, sameSite: 'lax', maxAge: 900, path: '/',
})
return response
}Pages Router:
// pages/api/contentbind-preview.ts
import type { NextApiRequest, NextApiResponse } from 'next'
export default function handler(req: NextApiRequest, res: NextApiResponse) {
const token = typeof req.query.token === 'string' ? req.query.token : ''
const redirect = typeof req.query.redirect === 'string' && req.query.redirect.startsWith('/')
? req.query.redirect : '/'
if (!token) return res.status(400).json({ error: 'token required' })
res.setHeader('Set-Cookie',
`contentbind_preview=${encodeURIComponent(token)}; Path=/; Max-Age=900; HttpOnly; SameSite=Lax; Secure`)
res.redirect(303, redirect)
}The page being previewed must read the cookie on the server - statically generated pages cannot see it. In the Pages Router that means getServerSideProps (or checking req.cookies.contentbind_preview); in the App Router, cookies() as below.
Draft mode
import { fetchOneEntry, isPreviewing, getPreviewToken } from '@contentbind/sdk'
import { cookies } from 'next/headers'
const jar = await cookies()
const entry = await fetchOneEntry({
model: 'page',
publicKey: KEY,
urlPath,
options: {
preview: isPreviewing(jar),
previewToken: getPreviewToken(jar),
},
})
if (isContentBindError(entry)) return nullWith preview set, delivery returns the draft and skips the cache entirely.
Share links
A preview link lets someone read a draft with no account: a designer, a legal reviewer, a client. Links can carry a password and an expiry, and can be revoked. The token grants one entry, not a workspace: it cannot be pointed at another page.
All documentation · llms.txt · llms-full.txt · contentbind.com