Course
Environment Variables
Next.js Mastery: From Fundamentals to Full-Stack
Unlock the power of Next.js with this comprehensive course! Starting with the basics, you’ll learn essential skills such as routing, data fetching, and styling. Progress through practical projects, including building your own React Notes app, to gain hands-on experience. Dive into the source code to understand the inner workings and core principles of Next.js. Perfect for developers with a basic knowledge of React and Node.js, this course ensures you’ll be ready to create high-performance full-stack applications efficiently. Join us and master Next.js, backed by industry experts and a supportive learning community.
Environment Variables
Introduction
In this article, we'll cover three important topics: environment variables, path aliases, and the
src
directory. Our main focus will be on how to use environment variables in Next.js. Next.js offers a powerful and user-friendly way to handle environment variables, making your development process smoother. Let's dive in!What Are Environment Variables?
Environment variables are settings that your operating system and applications use to control how things work. Think of them as global variables in programming—just like in JavaScript, where you have variables that all your functions can access. Environment variables are like that, but for your operating system and applications.
Common Commands
A commonly used environment variable is
PATH
, which tells your system where to find executable programs. If you're using macOS (or a similar Unix-based system), you can see all environment variables by running:printenv
This command will display a list of all environment variables. Something like this:
name@nanbunyuus-MacBook-Pro ~ % printenv__CFBundleIdentifier=com.apple.TerminalTMPDIR=/var/folders/rs/5dvnzf_d7jn91r90z418cvmw0000gn/T/XPC_FLAGS=0x0LaunchInstanceID=B764DBC2-3B86-42A9-9FR6-794E8318921TERM=xterm-256colorSSH_AUTH_SOCK=/private/tmp/com.apple.launchd.cPKvG7aiL6/ListenersSECURITYSESSIONID=124b2XPC_SERVICE_NAME=0TERM_PROGRAM=Apple_TerminalTERM_PROGRAM_VERSION=433TERM_SESSION_ID=F6E234A3-FFCF-491D-95F7-C6D8AEA67534SHELL=/bin/zshHOME=/Users/nameLOGNAME=nameUSER=namePATH=/Users/name/Library/pnpm:/Library/Frameworks/Python.framework/Versions/3.11/bin:/opt/homebrew/lib/ruby/gems/3.2.0/bin:/opt/homebrew/opt/ruby/bin:/Users/weny/.nvm/versions/node/v18.17.0/bin:/Library/Frameworks/Python.framework/Versions/3.11/bin:/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin:/Library/Apple/usr/bin:/Users/weny/.cargo/bin:/Users/weny/flutter/binSHLVL=1PWD=/Users/nameOLDPWD=/Users/nameHOMEBREW_PREFIX=/opt/homebrewHOMEBREW_CELLAR=/opt/homebrew/CellarHOMEBREW_REPOSITORY=/opt/homebrewMANPATH=/Users/name/.nvm/versions/node/v18.17.0/share/man:/opt/homebrew/share/man::INFOPATH=/opt/homebrew/share/info:NVM_DIR=/Users/name/.nvmNVM_CD_FLAGS=-qNVM_BIN=/Users/name/.nvm/versions/node/v18.17.0/binNVM_INC=/Users/name/.nvm/versions/node/v18.17.0/include/nodePNPM_HOME=/Users/name/Library/pnpmLANG=en_CA.UTF-8_=/usr/bin/printenv
To see a specific one, like
PATH
, you can use either of these commands:# Method 1printenv PATH
# Method 2echo $PATH
If you want to add or change an environment variable temporarily, you can use the
export
command:# 1. Set the variableexport MY_CUSTOM_VAR=example
# 2. Print the variable to check if it was set correctlyecho $MY_CUSTOM_VAR
This method is only temporary—it lasts until you close your terminal session. Sometimes, this is all you need, like when setting a variable in a
package.json
script:"scripts": { "dev": "export NODE_ENV=development && node index.js", "prod": "export NODE_ENV=production && node index.js"}
In your code, you can then access this variable using
process.env.NODE_ENV
:// Will log 'development' or 'production'console.log(process.env.NODE_ENV);
Making Changes Permanent
To make environment variable changes permanent, you need to modify your shell configuration files. If you're using
bash
, you'd typically edit ~/.bash_profile
. If you're using zsh
(the default on macOS Catalina and later), you'd edit ~/.zshrc
.For
bash
:# 1. Edit the filevim ~/.bash_profile
# 2. Add your variableexport MY_CUSTOM_VAR=example
# 3. Save and apply the changessource ~/.bash_profile
# 4. Check if it workedecho $MY_CUSTOM_VAR
For
zsh
:# 1. Edit the filevim ~/.zshrc
# 2. Add your variableexport MY_CUSTOM_VAR=example
# 3. Save and apply the changessource ~/.zshrc
# 4. Check if it workedecho $MY_CUSTOM_VAR
If you notice that changes aren't sticking after restarting your terminal, you might be using a different shell. You can check your current shell with:
echo $SHELL
To switch your shell:
chsh -s /bin/zsh # Switch to zshchsh -s /bin/bash # Switch to bash
Using
process.env
in Node.jsNode.js offers the
process.env
API, which provides access to environment variables. This is the standard way to retrieve environment variables in a Node.js application.{ TERM: 'xterm-256color', SHELL: '/usr/local/bin/bash', USER: 'maciej', PATH: '~/.bin/:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin', PWD: '/Users/maciej', EDITOR: 'vim', SHLVL: '1', HOME: '/Users/maciej', LOGNAME: 'maciej', _: '/usr/local/bin/node'}
Using Environment Variables in Next.js
Next.js simplifies the process of working with environment variables. There are two main ways to use them:
- Loading from
.env.local
: Next.js automatically loads environment variables from a.env.local
file intoprocess.env
.Here's how you can set up a.env.local
file in your project root (not inside thesrc
directory):
DB_HOST=localhostDB_USER=myuserDB_PASS=mypassword
You can then access these variables in your server-side code or API routes:
// app/page.jsexport default function Page() { console.log(process.env.DB_HOST) return <h1>Hello World!</h1>}
// app/api/route.jsexport async function GET() { const db = await myDB.connect({ host: process.env.DB_HOST, username: process.env.DB_USER, password: process.env.DB_PASS, }); // ...}
2. Exposing Variables to the Browser:
Normally,
process.env
variables are not available on the client-side. To expose them to the browser, prepend the variable name with NEXT_PUBLIC_
:Example:NEXT_PUBLIC_ANALYTICS_ID=abcdefghijk
You can then access this in your client-side code:
'use client';
export default function Page() { return <h1 onClick={() => console.log(process.env.NEXT_PUBLIC_ANALYTICS_ID)}>Hello World!</h1>;}
Without the
NEXT_PUBLIC_
prefix, the variable will be undefined
in the browser. When using the prefix, Next.js will replace process.env.NEXT_PUBLIC_ANALYTICS_ID
with the actual value during the build process.
Default Environment Variables
Next.js allows you to set default environment variables for different environments:
.env
for all environments.env.development
for development (used withnext dev
).env.production
for production (used withnext start
)
Additionally, if the
NODE_ENV
environment variable is not set, Next.js will automatically assign it as development
when running next dev
and production
for other commands. This helps developers distinguish between development and production environments.
Variables in
.env.local
will override these defaults.Note:.env
,.env.development
, and.env.production
are used to set default values. All these files can be placed in the repository, but.env*.local
should be added to.gitignore
because it may contain some confidential information.
Test Environment Variables
In addition to
development
and production
, there is a test
environment, used when running testing tools like Jest or Cypress. To set specific environment variables for testing, create a .env.test
file. Unlike the other environments, .env.test
does not load values from .env.local
, ensuring consistent test results.
Environment Variable Loading Order
Next.js loads environment variables in the following order. It stops at the first file that defines the variable:
process.env
.env.$(NODE_ENV).local
.env.local
(skipped ifNODE_ENV
istest
).env.$(NODE_ENV)
.env
For example, if you define
NODE_ENV
in both .env.development.local
and .env
, Next.js will use the value from .env.development.local
because it appears earlier in the order.