NextJS private dataset not working despite SANITY_API_READ_TOKEN in .env

2 replies
Last updated: Sep 7, 2023
Hi everyone!
I’m having issues with a private dataset in NextJS.
I can see the studio content populating my site on localhost with a public dataset, but not when I turn it to private.

I have added a SANITY_API_READ_TOKEN in my .env.local

What am I missing?
AI Update

The good news is that you're on the right track! When switching to a private dataset, you do need to use a token, which you've already added. Here are the key things to check:

1. Verify your token is being used in your client

Make sure your Sanity client configuration includes the token. In your Next.js app, this typically looks like:

import { createClient } from 'next-sanity'

export const client = createClient({
  projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID,
  dataset: process.env.NEXT_PUBLIC_SANITY_DATASET,
  apiVersion: '2024-01-01',
  useCdn: true, // This works fine with tokens!
  token: process.env.SANITY_API_READ_TOKEN,
})

Important note about useCdn: You CAN use useCdn: true with tokens for private datasets. Since JavaScript Client v3.0.0+, the Sanity CDN supports authenticated requests with caching segmented per token. Setting it to false will work, but isn't required and you'll miss out on the CDN's performance benefits.

2. Check your token placement

This is crucial - where you use the token matters for security:

  • Server-side only (recommended): Use SANITY_API_READ_TOKEN without the NEXT_PUBLIC_ prefix. This keeps the token secure and only accessible in server components, API routes, and server actions.
  • Client-side (not recommended): If you needed it in browser code, you'd use NEXT_PUBLIC_SANITY_API_READ_TOKEN, but this exposes your token publicly.

Your .env.local should look like:

NEXT_PUBLIC_SANITY_PROJECT_ID=your-project-id
NEXT_PUBLIC_SANITY_DATASET=your-dataset-name
SANITY_API_READ_TOKEN=your-token-here

3. Ensure your code is server-side

If you're using the token without the NEXT_PUBLIC_ prefix (which you should be), make sure you're fetching data in server components or API routes, not client components. In Next.js App Router, components are server components by default unless you add "use client" at the top.

4. Verify token permissions

Make sure your token has at least Viewer permissions for your dataset. You can check this in Sanity Manage:

  • Run npx sanity@latest manage from your command line
  • Navigate to the API tab
  • Check that your token has the appropriate role assigned

5. Restart your dev server

After adding or changing environment variables, you must restart your Next.js development server for the changes to take effect. Stop your server and run npm run dev (or yarn dev) again.

Common pitfall: Mixing client and server code

If you're seeing content on localhost with a public dataset but not with a private one, it's often because your fetching code is running client-side where the SANITY_API_READ_TOKEN environment variable isn't available (since it doesn't have the NEXT_PUBLIC_ prefix).

Check if you have "use client" in the file where you're fetching data. If so, you'll need to either:

  • Move your data fetching to a server component
  • Create an API route that uses the token server-side
  • (Not recommended) Use NEXT_PUBLIC_SANITY_API_READ_TOKEN if you absolutely need client-side access

After checking these items, your private dataset content should appear! Let me know if you're still having issues.

Show original thread
2 replies
👋 Your Next build won’t be able to pick up Sanity-specific env vars with that prefix. That method only works in a standalone Sanity instance. You shouldcheck out the Next documentation for how best to handle it.
I regenerated the token and it’s all good now!

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.

Was this answer helpful?