usePreviewSubscription not showing draft content in Next.js
I can see you're having trouble getting usePreviewSubscription to show draft content. This is a common issue, and there are several critical pieces that need to be in place for it to work properly.
The Most Common Issue: Missing or Misconfigured Token
The #1 reason drafts don't show up is a missing or improperly configured authentication token. The usePreviewSubscription hook needs a read token with appropriate permissions to access draft content. Check that you're passing it correctly:
const {data} = usePreviewSubscription(query, {
params,
initialData,
token: process.env.SANITY_API_READ_TOKEN, // Must have read permissions
})Without this token, the subscription can only access published documents, which matches exactly what you're experiencing.
Verify Preview Mode is Actually Enabled
Make sure preview mode is actually active when you're testing. You should have an API route (typically /api/preview) that enables it:
export default function preview(req, res) {
if (req.query.secret !== process.env.SANITY_PREVIEW_SECRET) {
return res.status(401).json({ message: 'Invalid token' })
}
res.setPreviewData({})
res.redirect(req.query.slug || '/')
}Then verify you're accessing your site through the preview URL (with the secret parameter), not just the regular published URL. Check your browser dev tools for the __prerender_bypass and __next_preview_data cookies - if they're not present, preview mode isn't active.
The overlayDrafts Pattern
Looking at the next-sanity minimal blog example you referenced, you need to use overlayDrafts in your getStaticProps to merge draft content over published content:
import {overlayDrafts} from './sanity'
export async function getStaticProps({params, preview = false}) {
const query = groq`*[_type == "post" && slug.current == $slug]`
const queryParams = {slug: params.slug}
const docs = await getClient(preview).fetch(query, queryParams)
// This merges drafts with published docs
const data = overlayDrafts(docs)
return {
props: {
data: data[0],
preview,
query: preview ? query : null,
queryParams: preview ? queryParams : null,
},
}
}The overlayDrafts helper is what actually prioritizes draft documents over published ones when both exist. Without this step, your query might return the published version even in preview mode.
Understanding How Drafts Work
When you edit a published document without publishing, Sanity creates a draft version with an ID prefixed by drafts. (e.g., drafts.post-123). Both the published and draft versions exist simultaneously in the Content Lake. The overlayDrafts function intelligently merges these, giving you the draft when it exists and falling back to published when it doesn't.
Quick Debugging Checklist
- Is preview mode actually enabled? (Check for cookies in dev tools)
- Are you passing a valid
tokentousePreviewSubscription? - Does your token have read permissions for the dataset?
- Is
getClient(preview)configured to use the token when preview is true? - Are you using
overlayDrafts()on the fetched data ingetStaticProps? - Is your draft actually saved? (Check in Studio that it exists with
drafts.prefix in the document inspector) - Are you accessing the site through the preview URL with the secret parameter?
Modern Alternative: Visual Editing
It's worth noting that usePreviewSubscription is part of an older preview approach. Sanity's current recommended solution is Visual Editing with Draft Mode, which provides a much better experience with:
- Real-time updates as you type in Studio
- Clickable overlays linking content to its source
- Better integration with the Presentation tool
With the modern approach using Draft Mode, you'd use the previewDrafts perspective in your queries, and the framework automatically handles showing draft content when preview mode is active.
The token configuration is almost always the culprit when drafts don't show up. Double-check that it's properly set in your environment variables, has the right permissions, and is being passed through to both your client configuration and the subscription hook.
Show original thread9 replies
Sanity ā Build the way you think, not the way your CMS thinks
Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.