loading...
Cover image for Environment Variables in Next.js

Environment Variables in Next.js

akhilaariyachandra profile image Akhila Ariyachandra Updated on ・3 min read

Updated my original blog post on 18th May, 2020 to reflect the how Next.js v9.4+ handles the .env file.

Often we need to use certain variables like the database path or authentication secrets without committing them to the repo.

Since Next.js uses Webpack we can use the dotenv-webpack dependency to load variable from a .env file to our Next.js application.

Let's start by installing dotenv-webpack as a dev dependency.

npm install dotenv-webpack -D

Next we need to modify the Webpack configuration in Next.js. This is done through the next.config.js file.

First import the dotenv-file dependency.

const Dotenv = require("dotenv-webpack");

Next export the config object with the default Webpack config function.

module.exports = {
  webpack: (config, { buildId, dev, isServer, defaultLoaders, webpack }) => {

    return config;
  }
};

All we need to do now is add the dotenv-plugin into the Webpack plugins array.

module.exports = {
  webpack: (config, { buildId, dev, isServer, defaultLoaders, webpack }) => {
    // Add the new plugin to the existing webpack plugins
    config.plugins.push(new Dotenv({ silent: true }));

    return config;
  }
};

Finally the next.config.js should look like this.

// next.config.js
const Dotenv = require("dotenv-webpack");

module.exports = {
  webpack: (config, { buildId, dev, isServer, defaultLoaders, webpack }) => {
    // Add the new plugin to the existing webpack plugins
    config.plugins.push(new Dotenv({ silent: true }));

    return config;
  }
};

Now you can use environment variables in the application. For example, if your .env file is like this,

AUTH_SECRET=verysecret

You can use the variable like this, process.env.AUTH_SECRET.

Never commit the .env file. Add it to the .gitignore file.

Deploying to Vercel

If you are using a Git provider like Github to deploy the Application in Vercel, you can't use .env file. This is the reason we set the silent property when adding dotenv-webpack plugin, to prevent any errors because of the missing .env file.

config.plugins.push(new Dotenv({ silent: true }));

Instead of the .env file we will use the Environment Variables UI available in Vercel.

To start, install, log into the Vercel CLI and link it to a project if you haven't already.

npm i -g now
now login
now

Then use the following command to set the Environment Variables in the deployment environment.

now env add

Finally to make the variables available in the client side code, we need to add one more property to the Next.js config. Add a new property called env and list all the environment variables you want in the client side code as follows.

// next.config.js
const Dotenv = require("dotenv-webpack");

module.exports = {
  webpack: (config, { buildId, dev, isServer, defaultLoaders, webpack }) => {
    // Add the new plugin to the existing webpack plugins
    config.plugins.push(new Dotenv({ silent: true }));

    return config;
  },
  // Have to list all the environment variables used here to make it available
  // to the client side code
  env: {
    AUTH_SECRET: process.env.AUTH_SECRET,
  },
};

This feels like a really hacky workaround to me, so if you have any suggestions on how to improve it please let me know in the comments below.

Wrapping up

You can find an example of the implementation here.

I hope you found this guide helpful. Please be sure to share it and leave a comment below! 😊

Posted on Mar 6 by:

akhilaariyachandra profile

Akhila Ariyachandra

@akhilaariyachandra

I'm just trying to share my love for javascript

Discussion

markdown guide
 

Hello Akhila. My name is Eranga from Colombo. I have a question. When we create a secrete using now secrets add. It's available in the Development environment. But how do we publish it to "Preview" and "Production" envoronments of Zeit. I am using Zeit now. The env variable is working fine in the Dev env. But it's undefined in the Prev and Prod envs. Any clue ?

 

ZEIT recently changed recently changed how the Environment Variables are handled, so I'll need to update the post to reflect that. From what I've tested so far, the now.json file and secrets are no longer needed. You just need to specify the variables with now env add. Hope it helps.

 

Thank you for replying. Yes, It's working without now.json and the secrets. But after we deploy it the values are not available(undefined) in the "Preview" environment.

Could you go to the project page in Vercel (ZEIT) and check if the variables are available for Preview? If not you can manually added from there.

Screenshot

Yes. I have set the values. We can create env values for all the environments locally using the now env add <VARIABLE NAME> command and publish to remote. Also we can add values directly on the settings page and pull them to the local using now pull env. I tried both ways. Unfortunately the values are available in local but not available on Preview in both cases. Bad luck

A workaround I found for now is to list all the variables you want in the client side code in the env property of the Next.js config.

env: {
    AUTH_SECRET: process.env.AUTH_SECRET,
}

I updated the post with more details.

 

Hi, I am having the same problem. This solution is working locally for development but when I deploy to preview or production the values are undefined.

Thanks for helping me get this far. It's nice to have a development working. If you have any idea how to get preview and production to work I would be truly in your debt.

 

A workaround I found for now is to list all the variables you want in the client side code in the env property of the Next.js config.

env: {
    AUTH_SECRET: process.env.AUTH_SECRET,
}

I updated the post with more details.

 

Sweet, thanks. I tried it and it's working. Very helpful.

 

Or you can just put all env vars in now.json and not commit it to github. Problem solved?

 

Not really because this won't make environment variables available in the ZEIT deployment environment.

 

It will when you deploy with now or now --prod(If you put actual envs not just "@now-auth-secret" references). I mean it works for me, not sure what kind of problems you've encountered

The purpose of using the .env file is to avoid committing sensitive data like the database URI or the JWT secret to the repo. In an ideal case we should avoid doing it at all costs, but if the variable isn't sensitive we could add it directly to now.json and commit it to the repo (though I still wouldn't recommend it).

Thats what my first comment was about, put envs in now.json and add it to git ignore. It serves the same purpose as .env

don't now.json files need to get commited though?
env files never get committed...
there's also a .nowignore file specifically to ignore now stuff.....

Came here because i'm in the same boat trying to "do it right" by using now secret and .env files locally, and the env variables UI at vercel.com.

None are working in preview/prod. only locally in dev.

If there is no config other than your envs in now.json, there is no need to commit it. Now.json file+Vercel is one of the ways to deploy your nextjs(or other) app, it's not integral part of you repo.

 

Seriously, THANK YOU. I've been struggling the whole day trying to make it works, but the Next.js doc was useless.
Thanks again

 

I talked to fast :p

It works well locally, but as soon as I test it on zeit (vercel), I have undefined on all my variables...

 

Did you upload the variables using now env add. Maybe I'll need to review my post again. I originally wrote it when we had to use Zeit secrets.

No but I managed to do something with this repo: github.com/zeit/next.js/tree/canar...

1) Create now.json and fill it like that :

{
  "build": {
    "env": {
      "SECRET": "@my-secret-key",
      "ANOTHER_SECRET": "@my-other-secret-key"
    }
  }
}

2) Then in your next.config.js you'll add module.exports:

module.exports = {
  env: {
    SECRET: process.env.SECRET,
  },
}

3) What worked for me at the end was to add my variables using "now secret add". I previously added my variable in the new variable UI on the website but it didn't work...

Hope this will help!

A workaround I found for now is to list all the variables you want in the client side code in the env property of the Next.js config.

env: {
    AUTH_SECRET: process.env.AUTH_SECRET,
}

I updated the post with more details. In the example I linked at the end of the post, I didn't use any secrets.