
Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag storeThis is a frustrating issue that often comes down to environment-specific differences between local and production. Based on your symptoms (works locally, 500 errors in production, cookie-related persistence), here are the most likely causes:
The "Not authenticated - preview not available" error typically means your preview token isn't being properly authenticated in production. Even though your dataset is public, Draft Mode requires an authenticated token to fetch draft content using the previewDrafts perspective.
Check:
SANITY_API_READ_TOKEN (or SANITY_API_TOKEN) environment variable is set correctly in production (Netlify/Vercel)previewDrafts perspective, not just published contentThe persistent 500 error when Draft Mode cookies are set suggests the cookies are causing issues with your server-side rendering. Next.js Draft Mode uses cookies (__prerender_bypass or __next-draft-mode depending on version) to track preview state.
Common issues:
Solution: Add an exit Draft Mode route so users can clear problematic cookies:
// app/api/disable-draft/route.ts
import { draftMode } from 'next/headers'
export async function GET() {
draftMode().disable()
return new Response('Draft mode disabled')
}Visit https://your-site.com/api/disable-draft to clear the cookies manually when things break.
If your Studio and Next.js site are on different domains, browsers may block third-party cookies, breaking Draft Mode authentication.
Check:
Your Draft Mode enable/disable API routes might be encountering errors in production that don't occur locally.
Verify:
/api/draft (or similar) route handler is deployed and accessible in productiondraftMode().enable() from next/headersExample Draft Mode enable route:
// app/api/draft/route.ts
import { draftMode } from 'next/headers'
import { redirect } from 'next/navigation'
export async function GET(request: Request) {
const { searchParams } = new URL(request.url)
const secret = searchParams.get('secret')
const slug = searchParams.get('slug') || '/'
// Validate secret
if (secret !== process.env.SANITY_REVALIDATE_SECRET) {
return new Response('Invalid token', { status: 401 })
}
draftMode().enable()
redirect(slug)
}Double-check these environment variables are set identically in both local and production:
SANITY_API_READ_TOKEN=<your-token-with-read-permissions> NEXT_PUBLIC_SANITY_PROJECT_ID=<your-project-id> NEXT_PUBLIC_SANITY_DATASET=<your-dataset> SANITY_REVALIDATE_SECRET=<your-secret-for-draft-mode-activation>
The SANITY_API_READ_TOKEN especially must be available server-side in production. On Vercel/Netlify, ensure you've set these in the dashboard and redeployed after adding them (adding env vars doesn't auto-redeploy).
Check production logs FIRST - This will save you hours. On Vercel, go to your deployment → Functions tab. On Netlify, check the Functions logs. The 500 error will have a stack trace showing exactly what's failing.
Test your API route directly - Visit https://your-site.com/api/draft?secret=YOUR_SECRET&slug=/ in production to see if it errors or successfully enables draft mode.
Inspect cookies - In production, open DevTools → Application → Cookies and check if the Draft Mode cookies are being set with proper attributes (domain, path, secure, samesite).
Test without Presentation tool - Try enabling Draft Mode by visiting the API route directly (not through Studio's Presentation tool) to isolate whether it's a Studio integration issue or a Draft Mode issue.
Try a fresh deployment - Sometimes stale build cache or function deployments cause issues. Trigger a fresh deploy with cleared cache.
In my experience, the most common cause is the SANITY_API_READ_TOKEN not being properly set in production environment variables. Since it works locally, you likely have it in your .env.local file, but it might be:
The second most common issue is the Draft Mode API route itself returning a 500 because it can't access environment variables or is encountering an error when trying to validate the secret. Check your production logs first - they'll give you the exact error message and point you directly to the problem.
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.
Content operations
Content backend


The only platform powering content operations
By Industry


Tecovas strengthens their customer connections
Build and Share

Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag store