Understanding how environment variables work in a Sanity-Next project

18 replies
Last updated: Jul 14, 2022
Just created a Sanity-Next project, but cant find out where the ProjectID is not set. The “.env.local” file is in the root folder of Sanity project.
AI Update

I can help you troubleshoot this "Project ID is not set" error! This is a common issue when setting up a Sanity-Next project, and it usually comes down to environment variable configuration and understanding the difference between Sanity Studio and Next.js environment variables.

Understanding the Two Different Systems

First, it's important to know that Sanity Studio and Next.js use different environment variable conventions:

  • Sanity Studio uses the SANITY_STUDIO_ prefix for its environment variables
  • Next.js uses the NEXT_PUBLIC_ prefix for client-side environment variables

These are separate systems with different requirements.

For Your Next.js Application

If you're getting the "Project ID is not set" error in your Next.js app (not in Sanity Studio), your .env.local file should be in the root of your Next.js application folder.

Create or edit .env.local in your Next.js root:

NEXT_PUBLIC_SANITY_PROJECT_ID="your-project-id-here"
NEXT_PUBLIC_SANITY_DATASET="production"

The NEXT_PUBLIC_ prefix is a Next.js requirement for exposing variables to client-side code. This has nothing to do with Sanity - it's how Next.js handles environment variables in the browser.

Then use these in your Sanity client configuration:

import { createClient } from '@sanity/client';

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,
});

For Sanity Studio (Different Use Case)

If you need environment variables in your Sanity Studio itself, you'd use a different approach with .env.development or .env.production files in your Studio folder:

SANITY_STUDIO_API_PROJECT_ID=your-project-id
SANITY_STUDIO_API_DATASET=production

Note the SANITY_STUDIO_ prefix instead. These are only for configuring the Studio application itself, not for your Next.js frontend.

Finding Your Project ID

You can find your Project ID in:

  • Your sanity.config.js or sanity.config.ts file (in the Studio folder)
  • The Sanity management console
  • By running sanity projects list in your terminal

The Project ID is not sensitive information - it will be visible in your frontend code and image URLs, so it's safe to commit to version control.

Common Project Structure

Many Sanity-Next projects have separate folders:

my-project/
├── studio/          (Sanity Studio - uses SANITY_STUDIO_ variables)
└── app/             (Next.js app - needs NEXT_PUBLIC_ variables in .env.local)

Make sure your .env.local is at the root of wherever your Next.js package.json is located.

Important Final Steps

  1. Restart your dev server: After creating or modifying .env.local, you must restart your Next.js development server
  2. Check your client configuration: Verify that your Sanity client is actually reading process.env.NEXT_PUBLIC_SANITY_PROJECT_ID
  3. No typos: Double-check spelling in both your .env.local file and where you reference the variables

The key takeaway: NEXT_PUBLIC_ is for Next.js client-side code, while SANITY_STUDIO_ is specifically for Sanity Studio configuration. For a Next.js app consuming Sanity data, you'll use NEXT_PUBLIC_ prefixed variables.

You may already know this, but at the time I experienced something similar, I didn't.
When you add things to env files, even local ones, you have to restart the server for it to know they exist.

If you haven't already, give that a go and see if it helps.
Really? I didnt know that so thank you!! ill try that for sure
It was pretty frustrating because I look for answers and facts like that proactively and somehow missed it. So I was hooking up to a database and it was autocompleting the process.env. and then my key but only for one variable.
I thought I was losing it haha

It just so happened that I had closed out of my IDE so the one that was already there was recognized, but not the one I just added.
That’s because your environment is bootstrapped on server start, not at run time.
I think a way to understand why it behaves like this is to see your server as a Node process on an entry file, like
node index.js
. It’s started once and then it just runs as a Node server.
Environment variables (from your
.env.local
file) are fed to that process on start like so:
FOO=bar BAZ=qux node index.js
. So updating that
.env.local
does not actually restart the process. 🙂
Yeah once I realized what was going on I totally got it. So much is made conveniently magic out there that I didn't realize it. Reminds me a bit of php.ini files. At shared hosting a lot of times you don't see it. You place it or change it and get told to check back in ten minutes. At Digital Ocean I'm the button pusher or shell person, but in either case the original ongoing process can't continue on absorbing the new info. I need to restart.
Could there be any other reason why it wont its telling me its not set? Tried to restart, but that didnt help. https://www.sanity.io/guides/sanity-nextjs-tailwindcss#06805025f551 Followed this tutorial.
Where is the error coming from? Your Sanity client? In which case, how do you instantiate it?
This may also be too simple an answer, but are you sure you have saved your .env file? Have you checked your sanity.json file? it also has an api with your Sanity projectId.
The error is coming from Sanity. I have saved the .env file and checked my sanity.json file, it has the same projectID as in the studio
is the way im writing this line wrong? The file name is
.env.local



NEXT_PUBLIC_SANITY_PROJECT_ID=tgymg0pq
and should the .env.local file be in root folder or Sanity folder?
In the root folder. It’s Next.js’ env file.
How do you instantiate your Sanity client please?
./lib/sanity.js
import {
  createClient,
  createPortableTextComponent,
  createImageUrlBuilder,
  createPreviewSubscriptionHook,
} from "next-sanity";
import ReactTooltip from "react-tooltip";

import { config } from "./config";

if (!config.projectId) {
  throw Error("The Project ID is not set. Check your environment variables.");
}
export const urlFor = (source) => createImageUrlBuilder(config).image(source);

export const imageBuilder = (source) =>
  createImageUrlBuilder(config).image(source);

export const usePreviewSubscription = createPreviewSubscriptionHook(config);

// Set up Portable Text serialization
export const PortableText = createPortableTextComponent({
  ...config,
  // Serializers passed to @sanity/block-content-to-react
  // (<https://github.com/sanity-io/block-content-to-react>)
  serializers: {
    types: {
      code: (props) => (
        <pre data-language={props.node.language}>
          <code>{props.node.code}</code>
        </pre>
      ),
    },
  },
});

export const client = createClient(config);

export const previewClient = createClient({
  ...config,
  useCdn: false,
});

export const getClient = (usePreview) => (usePreview ? previewClient : client);
export default client;
./lib/config.js

export const config = {
  /**
   * Find your project ID and dataset in `sanity.json` in your studio project.
   * These are considered "public", but you can use environment variables
   * if you want differ between local dev and production.
   *
   * <https://nextjs.org/docs/basic-features/environment-variables>
   **/
  dataset: process.env.NEXT_PUBLIC_SANITY_DATASET || "production",
  projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID,
  apiVersion: "2021-08-11", // or today's date for latest
  /**
   * Set useCdn to `false` if your application require the freshest possible
   * data always (potentially slightly slower and a bit more expensive).
   * Authenticated request (like preview) will always bypass the CDN
   **/
  useCdn: process.env.NODE_ENV === "production",
};
Alright, so your own code throws that error. That’s good to know because I couldn’t figure out where that error was actually coming from.
Does this error happen only in production or locally as well?

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?