Issue with Next JS SSG preview mode and `next-i18next` package causing 500 error on Netlify
This 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:
1. Token Authentication Issues
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:
- Verify your
SANITY_API_READ_TOKEN(orSANITY_API_TOKEN) environment variable is set correctly in production (Netlify/Vercel) - Ensure the token has proper read permissions for your dataset
- The token should work for the
previewDraftsperspective, not just published content - Make sure it's set as a secret (server-side) environment variable, not a public one
2. Cookie Configuration and Stale State
The 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:
- Cookies set with incorrect domain attributes
- Cookie security settings (SameSite, Secure) not compatible with your production setup
- The server-side code encountering errors when trying to process the draft mode state
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.
3. CORS and Third-Party Cookie Blocking
If your Studio and Next.js site are on different domains, browsers may block third-party cookies, breaking Draft Mode authentication.
Check:
- Are you accessing preview from the Studio's Presentation tool on a different domain?
- Try accessing the preview directly on your production domain (not embedded in Studio)
- Verify CORS settings in your Sanity project (manage.sanity.io → Settings → API → CORS Origins) include your production domain with "Allow credentials" enabled
- Test in an incognito window to rule out browser extension interference
4. API Route Configuration and Errors
Your Draft Mode enable/disable API routes might be encountering errors in production that don't occur locally.
Verify:
- Your
/api/draft(or similar) route handler is deployed and accessible in production - It's properly enabling draft mode using
draftMode().enable()fromnext/headers - The route validates your preview secret/token before enabling
- Check your production logs (Vercel Functions tab or Netlify Functions logs) for the actual error when the 500 occurs
Example 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)
}5. Environment Variable Mismatch
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).
Critical Debugging Steps
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.
Most Likely Culprit
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:
- Missing entirely from Vercel/Netlify
- Named differently in production
- Not available to the serverless functions
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 – 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.