- Published on
Next.js Environment Variable Support and the .env.local File
- Authors
- Name
- interglobalmedia
- @letsbsocial1
This post was first published on my Next Blog
mariadcampbell.com on Sunday, February 19, 2023.
Previously, I had written a post
about using dotenv
with Next.js
, and also adding the NEXT_PUBLIC
prefix in front of environment variable
names. Adding NEXT_PUBLIC
and then placing process.env
in front of the environment variable
name and using it directly like that in your code will expose it to the browser
. And you have to add NEXT_PUBLIC
in order for that to happen. So something like the following:
const data = { email, api_key: process.env.NEXT_PUBLIC_CONVERTKIT_API_KEY }
would be exposed to the browser
. However, the following:
const API_KEY = process.env.NEXT_PUBLIC_CONVERTKIT_API_KEY
const data = { email, api_key: API_KEY }
would not, because it is saved as the value
of a variable
. And that is the way I have always approached my environment variables
, especially when using dotenv
. Which is what I do in the case of my business site
.
However, I found out later, that this is redundant
with Next.js
. It is not necessary to use dotenv
in order to be able to extract one’s environment variable
values from the .env.local
file.
It is important to note that you have to save your environment variables
in your .env.local
file. That is where Next.js
expects you to keep your secrets
.
It is also (most) important to note that you have to add your .env.local
file to your .gitignore
file immediately upon creation
of your project before having committed
and pushed
any changes to remote. This is both so you don't forget to do so later, and to ensure that your sensitive information
stored as the values
of your variables
are never exposed on Github
or wherever else. Next.js'
create-next-app
does create a .gitignore
file for you, and does include the .env*.local
file there for you already, but if you are new to all this, it is good practice to double check the file. The .env
file is NOT added there. That is meant for non-sensitive, default env var
values, and therefore does not need to be included in .gitignore
.
Below is what I have in my next.config.js
file for my Next Blog
which I am in the process of building, and in which I have set up both environment variables
for development
and production
:
const webpack = require('webpack')
const withBundleAnalyzer = require('@next/bundle-analyzer')({
enabled: process.env.ANALYZE === 'true',
webpack: (config, { dev, isServer }) => {
config.module.rules.push({
test: /\.svg$/,
use: ['@svgr/webpack'],
})
if (!dev && !isServer) {
// Replace React with Preact only in client production build
Object.assign(config.resolve.alias, {
'react/jsx-runtime.js': 'preact/compat/jsx-runtime',
react: 'preact/compat',
'react-dom/test-utils': 'preact/test-utils',
'react-dom': 'preact/compat',
})
}
if (isServer) {
require('./scripts/generate-sitemap')
}
if (!isServer) {
require('./scripts/compose')
}
return config
},
})
/** @type {import('next').NextConfig} */
const nextConfig = {
/* Configure pageExtensions to include md and mdx */
pageExtensions: ['ts', 'tsx', 'js', 'jsx', 'md', 'mdx'],
/* Optionally, add any other Next.js config below */
reactStrictMode: true,
}
module.exports = withBundleAnalyzer(nextConfig)
No evidence of env vars
. No evidence of dotenv
.
By default, Next.js
provides us with 3 different environments
. The environments
available through Next.js
by default are development
, production
, and test
.
The way that I can differentiate between and even use both development
and production
environments
locally , is I create an .env.development.local
file for my development
env vars (short for environment variables
), and an .env.production.local
file for my production
env vars. I do this to test my production
environment/build before I push
to remote
to avoid unexpected surprises
.
However, and this is very important
, I keep the env var
names the same across environments
and in the code
. Otherwise, only one environment
, the one defined in the code
using ONE SET of env vars
, will work.
AND, also very important
, the env var
names have to match
on vercel.com
as well. So if I name my env var
for my MongoDB database
MONGODB_DATABASE
in the code
, then it has to be defined as MONGODB_DATABASE
in both the .env.development.local
file AND the .env.production.local
file. Just the values
are different. And these two files
are what I use on my local machine
to switch between development
and production
.
When I run npm run dev
, the env vars
in .env.development.local
are extracted. And when I run npm start
AFTER running npm run build
to build
my application
's production code
, then tbe env vars
in .env.production.local
are extracted.
Lastly, I have to add my env vars
to my project
on vercel.com
. There, I also have to name
the env var
MONGODB_DATABASE
, and add the value
I want for production
there. THEN everything works as expected both on my local machine
AND on my remote server
.
No need to require
and call
dotenv
as I had done in the past. This was not wrong, but it means one less dependency to include, which is good for application optimization
.
The Next.js
documentation regarding support
for environment variables
is pretty good, and if you already have been using environment variables
with dotenv
in your Node.js
projects in the past, it will be fairly easy to follow. I will be including reference
to the Next.js
documentation at the end of the post
under Related Resources
.
Happy Next.js developing with env vars!
Related Resources
How to use different .env files with nextjs?: stackoverflow
Environment Variables: Next.js docs