Setting up dotenv in Next.js
Existing Setup
I was working on a task to adopt dotenv in our project. We had all our environment variables in a separate file (.env) and we used to source it manually before running the application. It was okay for a while but we needed a better solution.
Research
As we use Next.js in our project, I thought of just using its built-in feature to populate the process.env but it had some limitations,
- The .env file had to be in the root directory.
- To expose a variable to the browser, the variable had to be prefixed with “NEXT_PUBLIC”.
- Plus, the .env itself needed “export” or “set” keyword for each variable depending on the OS, which is again, not that comfortable.
These are limitations because some of us like to keep our .env files in a different location rather than the root directory. And adding prefixes like “NEXT_PUBLIC”, “export”, or “set” produces a lot of noise in the code and makes sharing difficult with people using different operating systems like Windows and Linux or Mac. Windows requires “set” and the other two require “export”.
Solution
dotenv → Next.js
Load once in config, skip OS export noise
Point: wire dotenv in Next config so custom paths work and you drop export/set noise per OS.
So we decided to use dotenv along with Next.js. Here’s how you can do it too,
First, create a .env file for your project and save it somewhere:
API_HOST=https://exampleapi.com
Put your environment variables in the file, one per line.
Then, install dotenv module:
npm install dotenv
Typically in a node application, we could just invoke dotenv using the following command:
require('dotenv').config({ path: '/full/custom/path/to/env' })
But in case of a Next.js application, we need to do this in the Next.js config.
Next.js Config Modifications
Next.js provides a couple of interesting hooks in the next.config.js file. One of them is the webpack hook. We can use this to provide the environment variables to webpack so that when it builds the browser bundle of JavaScript, it can make the necessary replacements for the browser environment.
Normally, process.env is not available in browsers, but Next.js runs in the server as well as in the browser. Here’s what you need to do:
In the Next.js config file import webpack:
const webpack = require('webpack')
Next, import dotenv and configure your .env file:
const { parsed: myEnv } = require('dotenv').config({
path: '/full/custom/path/to/env'
})
Here, parsed object is destructured from dotenv. Usually, this will be set in process.env but now it can be passed to the webpack.EnvironmentPlugin to do the replacements, like this,
module.exports = {
webpack(config) {
config.plugins.push(new webpack.EnvironmentPlugin(myEnv))
return config
}
}
Now in the app, wherever you use process.env.API_HOST, the final bundle will be output with the actual URL.
This way, you don’t need to add any sort of prefixes or the “export” and “set” keywords. This comes handy when sharing the .env file with someone that uses a different OS. And since we don’t need to source it manually every time, we could just place the .env file in some folder and forget about it.
Note: If the .env file is located in the root of the project, we don’t have to specify the path.
I hope you learnt something new or maybe even solved a problem. Thanks for reading, have fun!
Originally published on Medium.