Strategies for draft changes visible in preview but not production
Great question! The key to this workflow is using perspectives to control which version of your content gets fetched. Here's how teams typically handle this:
The Core Strategy: Perspectives
Sanity's perspectives feature lets you query different views of your content. The most important ones for your use case are:
published- Only returns published documents (for your live site)previewDrafts- Returns draft versions when they exist, otherwise falls back to published (for your preview builds)
Implementation with Next.js
The most common approach uses Next.js Draft Mode (formerly Preview Mode) to handle this automatically:
1. Set up different query configurations:
For your live site, use the published perspective:
const client = createClient({
projectId: 'your-project',
dataset: 'production',
useCdn: true,
apiVersion: '2025-02-19',
perspective: 'published' // Only published content
})For your preview build, use previewDrafts with authentication:
const previewClient = createClient({
projectId: 'your-project',
dataset: 'production',
useCdn: false,
token: process.env.SANITY_API_READ_TOKEN, // Required for drafts
apiVersion: '2025-02-19',
perspective: 'previewDrafts' // Drafts + published fallback
})2. Enable Draft Mode in Next.js:
When editors click a preview link from Studio, it activates Draft Mode via a cookie, which tells your app to use the preview client instead of the production one. This means:
- Draft changes appear in your preview deployment
- Published content stays unchanged on your live site
- No manual switching required
Alternative: GROQ Query Filtering
If you're not using Draft Mode, you can filter drafts directly in your GROQ queries:
For production (exclude drafts):
*[_type == 'post' && !(_id in path("drafts.**"))]For preview (prioritize drafts):
*[_type == 'post'] | score(_id in path("drafts.**")) | order(_score desc)This second query ranks draft documents higher, so they appear first when both versions exist.
How Draft/Published Documents Work
When you make changes in Studio without publishing, Sanity creates a draft document with an ID like drafts.post-123, while the published version stays as post-123. They exist as separate documents until you hit publish, which merges the draft into the published version.
The previewDrafts perspective automatically handles this by showing the draft version when it exists, or falling back to published if there's no draft—perfect for preview environments.
Best Practices
- Use environment variables to control which client/perspective gets used based on deployment environment
- Secure your preview token - never expose it in client-side code
- Consider using Visual Editing if you want editors to preview changes directly in Studio with the Presentation tool
This setup gives you the flexibility to iterate on drafts while keeping your live site stable!
Show original thread4 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.