110

I am coding a website with Next.js and I tried to add google Tag Manager.
I followed the tutorial on the Next.js Github example but for some reasons I can't access to my environment variables.
It says my variable is undefined.
I created a file .env.local on my project folder (at the same level as components, node_modules, pages, etc)
In this file I created a variable like this (test purpose) :

NEXT_PUBLIC_DB_HOST=localhost

And on my index page I tried this code :

console.log("test ", process.env.NEXT_PUBLIC_DB_HOST);

But in my console I get a "test undefined".
I tried to put my variable into an .env file instead, without success.
What I am doing wrong ?

6
  • 13
    Have your tried to reload next server? Commented Feb 10, 2021 at 12:59
  • I'm not sure to understand what you mean. I stopped what was in my vscode terminal and did a yarn dev again. Is there anything else to do to reload the next server ? Commented Feb 10, 2021 at 14:36
  • 1
    Yep, just that. It did not help? Are you sure that .env file at the same level as package.json? Not quite sure what else can help. Commented Feb 10, 2021 at 15:29
  • 6
    Ok, I'm stupid ! I found my mistake... I put a ":" instead of a "=". I'm ashamed... Commented Feb 11, 2021 at 7:18
  • Thanks a lot @FlorieAnstett I did the same mistake and wasted more than 2 hours Commented Sep 29, 2021 at 15:05

20 Answers 20

184

This envs just works in Server Side. To access this envs in Client Side, you need declare in the next.config.js

This way:

module.exports = {
  reactStrictMode: true,
  env: {
    BASE_URL: process.env.BASE_URL,
  }
}
Sign up to request clarification or add additional context in comments.

4 Comments

As of Nextjs version 9.4 next.config.js is no longer suggested as the environment strategy. Are you using an older version of NextJS or do you find this to be the only way to have success?
I was just having this issue and this resolved my error while on Next 10.0.3
On Next +9, prefix the variables using NEXT_PUBLIC_. This will expose them on the browser.
I am on Next 12.1 and "NEXT_PUBLIC_" did not work for me even after restarting the server. This did
95
  1. Create .env (all environments), .env.development (development environment), and .env.production (production environment).

  2. Add the prefix NEXT_PUBLIC to all of your environment variables.

NEXT_PUBLIC_API_URL=http://localhost:3000/

  1. Use with prefix process.env

process.env.NEXT_PUBLIC_API_URL

  1. Stop the server and restart it:

npm run dev

  1. This solution for version 9.4.0 and above.

3 Comments

Note that it if you try to console log it will only log to your terminal not your browser console
@msmfsd it logs into the browser console as well, then what's the use of doing NEXT_PUBLIC_. it makes it accessible on the client side
i did this and browser console still says "process is not defined." are there any additional steps that it's assumed we already know?
41

For those using NextJS +9 and looking for environment variables in the browser, you should use the NEXT_PUBLIC_ prefix. Example:

NEXT_PUBLIC_ANALYTICS_ID=123456789

See documentation for reference.

Comments

26

Restarting the server worked for me.

  1. Edit & save .env.local
  2. Stop the server and restart it, npm run dev
  3. You should get an output on the next line like this:
> [email protected] dev
> next dev

Loaded env from [path]/.env.local

Comments

24

After spending countless hours on this, I found that there is a tiny little paragraph in both the pre and post nextjs 9.4 documentation:

Key words being BUILD TIME. This means you must have set these variables when running next build and not (just) at next start to be available for the client side to access these variables.

2 Comments

Ugh, this was the key for me. I had set these vars using an npm script, but it was after build time, but before starting my server.
I do get this issue. Then my question is: when in development, I have my API key which I want to keep with server side. How am I going to debug the code where it uses the API key in the server side without building the project?
11

For video reference codegrepper link https://youtu.be/6qhF9l_AgAk

process.env only work in server not in browser so it will show undefined to fixed it use NEXT_PUBLIC_before APi key in .env.local or .env this solution only work from version 9 of nextjs.

NEXT_PUBLIC_BACKEND_API="http://localhost:1337/graphql"

secret environment like MongoURl and openAi key shouldn't be put using Next_PUBLIC_ else it will expose to browser and everyone can use it.

MONGO_URL=

OPENAI_API_KEY=

Comments

4

Late to the party, but no answer here works for me for nextjs 14.

Simple solution is reading env on server side and pass it to the client component:

export const SSRComponent = () => {
  return <ClientComponent baseUrl={process.env.BASE_URL} />
}

While NEXT_PUBLIC_ prefix works well for dev mode, for production mode it works only if env values substituted by build time

Note: After being built, your app will no longer respond to changes to these environment variables. For instance, if you use a Heroku pipeline to promote slugs built in one environment to another environment, or if you build and deploy a single Docker image to multiple environments, all NEXT_PUBLIC_ variables will be frozen with the value evaluated at build time, so these values need to be set appropriately when the project is built. If you need access to runtime environment values, you'll have to setup your own API to provide them to the client (either on demand or during initialization).

From devops prospective injecting env build time means different image for each combination of env values, it's a nightmare and most likely no-go solution.

Comments

3

This is my next.config.js file.

/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: true,
  env: {
    BASE_URL: process.env.NEXT_PUBLIC_SITE_URL,
  },
};

module.exports = nextConfig;

Restart the server and it worked fine. using Nextjs 12.1.0 with typescript

1 Comment

Do you use dotenv or something? Doesn't work for me. But I'm using inside monorepo, which have dotenv dependency in one of other package
3

Adding with the most recent version of the documentation on this, v12+.

Using the next.config.js file you can specify server and client variables:

module.exports = {
  serverRuntimeConfig: {
    // Will only be available on the server side
    mySecret: 'secret',
    secondSecret: process.env.SECOND_SECRET, // Pass through env variables
  },
  publicRuntimeConfig: {
    // Will be available on both server and client
    staticFolder: '/static',
  },
}

You can still use an env.local file, and pass the variable in to the next.config.js file. For example:

 publicRuntimeConfig: {
   DB_URL: process.env.DB_URL
 }

And then you can access the variable like this:

import getConfig from 'next/config';
const { publicRuntimeConfig } = getConfig();
publicRuntimeConfig.DB_URL;

Comments

3
  1. Ensure that your .env file is located at the root of your project and not within the .src/ directory.
  2. Utilize NEXT_PUBLIC_"name of your variable" for setting up your environment variable.
  3. Restart the server.

Comments

1

In my case, Im pasting REACT_APP_API_URL instead of NEXT_PUBLIC_API_URL.

Comments

1

from document https://nextjs.org/docs/pages/building-your-application/configuring/environment-variables

use NEXT_PUBLIC_[...] exp: NEXT_PUBLIC_API_URL

1 Comment

As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
1

This is very simple, I don't know why people are making this so complex, Just follow the below said steps.

  1. Please keep your .env.local file inside the project root directory myproject/.env.local

  2. Environment variable sample under .env.local is following -

    NEXT_PUBLIC_MY_PACIFIC=Asia

  3. Please restart your server, by stopping the server and again starting it (mandatory).

  4. Use Environment variable as following -

    process.env.NEXT_PUBLIC_MY_PACIFIC

This is what you all have to do, I've done in version NextJS 14.0 , Hope it would help many one.

Comments

0
  1. Check Your .Env Files:

    Make sure you've got defined your surroundings variables in an appropriate .Env documents. In Next.Js, you may use one-of-a-kind .Env files for exceptional environments (e.G., .Env.Local for neighborhood development and .Env.Production for manufacturing). Ensure that the variables you're looking to get entry to are defined in the correct .Env file.

  2. Restart Your Development Server:

    After adding or enhancing environment variables, ensure to restart your development server. Sometimes, modifications to surroundings variables won't take effect until the server is restarted.

  3. Use process.env to Access Environment Variables:

    In Next.js, you can access environment variables use of process.env. For example:

const myVar = process.env.MY_VARIABLE;

Comments

0

process.env only works in server not in browser so it will show undefined. To fix it, use NEXT_PUBLIC_ before APi key in .env.local or .env. This solution works.

Comments

0

Here's a very obvious debugging tip, that actually caught me for a couple hours today. Temporarily use this debug code to check for typos. If you don't see a convenient place to put it in the file throwing the error, put this in the page or component that calls uses that file.

console.log(process.env)

Comments

0

if you have dotenv package config with path then just remove that line.

it's works for me.

Comments

0

What worked for me was this package next-runtime-env.

I tried a lot of the solutions above and eventually found this blog post that kind does it in the same fashion as the package if you don't what the extra dependency. It was also this same blog post that refered the package above.

Example from the package docs:

In your app/layout.tsx, add:

// app/layout.tsx
import { PublicEnvScript } from 'next-runtime-env';

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <head>
        <PublicEnvScript />
      </head>
      <body>
        {children}
      </body>
    </html>
  );
}

Access your environment variables easily:

// app/client-page.tsx
'use client';
import { env } from 'next-runtime-env';

export default function SomePage() {
  const NEXT_PUBLIC_FOO = env('NEXT_PUBLIC_FOO');
  return <main>NEXT_PUBLIC_FOO: {NEXT_PUBLIC_FOO}</main>;
}

Comments

0

If you're building your app with Docker, ensure that all variables with the NEXT_PUBLIC_ prefix are included in the Docker build step, typically by defining them in the .env.production file.

Comments

0

None of the approaches above work on a CI/CD pipeline, in my case Azure GitHub Actions. The fundamental problem is that the build executes in the cloud and doesn't have access to production environment variables. Normally in Azure, you put sensitive env variables in the Environment section of the Web App config, but this simply doesn't work for a NextJS app because the environment variables are bound at build time. So you need to provide the sensitive environment variables (API keys and so on) to the build process of the pipeline. You could of course check in your env.production file, but this completely defeats security. If your sensitive env variables are in the code base they are, by definition, no longer sensitive.

The way to do this is to add the env variables to the build script. So for my GitHub actions it looks like this...

      - name: npm install, build, and test
        run: |
          npm install
          npm run build --if-present
          npm run test --if-present
        env:
          NEXT_PUBLIC_SECRET_API_KEY: abc-xxxxxxxxxxx

But wait! The GitHub action script is checked into the code repository!

Indeed. This is not good enough. So take this the final mile we need to use GitHub secrets. So create a production environment for the repo and add the API key to it. Now the build script looks like this...

jobs:
  build:
    runs-on: ubuntu-latest
    environment: production  # add this to select the environment
    permissions:
      contents: read #This is required for actions/checkout

    steps:
      - uses: actions/checkout@v4

      - name: Set up Node.js version
        uses: actions/setup-node@v3
        with:
          node-version: '20.x'

      - name: npm install, build, and test
        run: |
          npm install
          npm run build --if-present
          npm run test --if-present
        env:
          NEXT_PUBLIC_SECRET_API_KEY: ${{ secrets.NEXT_PUBLIC_SECRET_API_KEY }}

Now you are fully protected and your production API key will be available in production.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.