Environment Variables in Next.js

Here's a way to get environment variable values into your Next.js app.

Why in the Environment?

Why might you want to put variables into the environment? These might be values that are sensitive that you don't want to commit to source control. They might be things that change per environment (staging vs production). They might be things you want to be able to adjust without changing your code.

An example of a thing that we might want to change in an environment variable is the url for an API host that our Next.js site connects to for data.

Node Environment Variables

In Node, and thus in Next.js, we access environment variables via process.env. This is a map of different values available from the environment. If I set the variable in the environment and then ran my next app:

export API_HOST=https://exampleapi.com
next

Then I could access the variable in my Node code with:

process.env.API_HOST

Instead of typing export every time I want to modify the environment for my app, I create a list of variables for the app process to have automatically every time I run it. I can do this with a little tooling and setup.

Dotenv Module

First, create a .env file in your project root:

API_HOST=https://exampleapi.com

Put your environment variables in that file, one per line.

Then install a dotenv module for your Next.app to use to load this file:

npm install dotenv

In your node code, you need to invoke dotenv to load the .env file contents into the environment. This is done with:

require('dotenv').config()

But where should this call go in your Next.js app?

Next.js Config Modifications

Out of the box, the Next.js config doesn't have anywhere specifically to put environment variables. But Next.js does provide extensibility via a couple interesting hooks in the next.config.js file in your project root. One hook is the webpack hook, where we can access and change anything in webpack.

We need to provide the environment variables to webpack so that when it builds the browser bundle of JavaScript it can make the needed string replacements for the browser environment.

Specifically, process.env isn't available in the browsers (only Node.js), but your Next.js code runs in both places. So the browser bundle that is generated by webpack needs to replace, for instance, process.env.API_HOST with "https://exampleapi.com".

To do this, edit next.config.js to include:

const { parsed: localEnv } = require('dotenv').config()
const webpack = require('webpack')

module.exports = {
  webpack(config) {
    config.plugins.push(new webpack.EnvironmentPlugin(localEnv))

    return config
  }
}

Here, we call dotenv.config(), and we destructure out the parsed object -- usually set on process.env, but now given to the webpack.EnvironmentPlugin -- which will do the string replacement.

Now inside your Next.js code, you can use the environment variable process.env.API_HOST, and the final bundle will be output with "https://exampleapi.com". You're probably using this inside of getInitialProps or wherever you're calling your API.

What alternate methods do you use to set environment variables in your Next.js projects?