Sanity preview "Not authenticated" error with Next.js
I see you're hitting the "Not authenticated - preview not available" error with Next.js and Sanity. This is a common issue with Draft Mode and Visual Editing, and that flash of content before the 404 is a key clue about what's happening.
What's Causing This
The error typically stems from cookie-based authentication failing in Next.js Draft Mode. According to the Draft Mode troubleshooting documentation, when your Sanity Studio and Next.js site are on different domains (or even different subdomains), browsers can block the third-party cookies that Draft Mode relies on for authentication. The flash you're seeing is the page briefly loading before the authentication check fails and redirects to a 404.
Solutions to Try
1. Check Your Draft Mode API Route
Make sure you have a Draft Mode enable route set up. For Next.js App Router, create app/api/draft-mode/enable/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 slug = searchParams.get('slug')
(await draftMode()).enable()
redirect(slug || '/')
}2. Configure Your Presentation Tool
In your sanity.config.ts, the Presentation tool needs to point to your draft mode endpoint:
import { presentationTool } from 'sanity/presentation'
export default defineConfig({
plugins: [
presentationTool({
previewUrl: {
previewMode: {
enable: '/api/draft-mode/enable',
},
},
}),
],
})3. Verify Your Authentication Token
Check that your SANITY_API_READ_TOKEN environment variable is:
- Set correctly in your
.env.localfile (for local development) - Configured in your hosting platform's environment variables (for production)
- Has the proper read permissions in your Sanity project settings
According to the Visual Editing with Next.js guide, when you use defineLive from next-sanity/live, you configure tokens like this:
import { defineLive } from 'next-sanity/live'
import { client } from './client'
export const { sanityFetch, SanityLive } = defineLive({
client,
browserToken: process.env.NEXT_PUBLIC_SANITY_API_READ_TOKEN,
serverToken: process.env.SANITY_API_READ_TOKEN,
})4. Check CORS Configuration
If your Studio and frontend are on different domains, ensure CORS is properly configured:
- Go to your Sanity project settings (Manage → API → CORS Origins)
- Add your frontend URL (including localhost for development)
- Enable "Allow credentials"
5. Browser Cookie Settings
The Draft Mode troubleshooting docs mention that if browsers block third-party cookies, you may need to provide explicit token and EventSource props to subscription hooks as a workaround.
Why This Started "Suddenly"
If this just started happening today, possible causes include:
- Token expiration or revocation - check if your API token was recently regenerated
- Environment variable issues - recent deployment that didn't properly load env vars
- Browser update - Chrome periodically tightens cookie policies
- Domain changes - any recent changes to your hosting setup or URLs
Try checking your browser console for additional error messages and verify your token is valid in your Sanity project settings. If you recently deployed, double-check that all environment variables made it to your hosting platform correctly.
Show original thread3 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.