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?