Next.js Environment Variables: Built-In, Public, and Private

Nextjs Environment Variables Blog banner

What Are Next.js Environment Variables? 

Environment variables are dynamic-named values that can impact the way running processes behave on a device. They exist in almost all operating systems, and they often include information such as drive, pathname, or filename.

For Next.js developers, environment variables provide a way to store data that our application needs to function correctly at runtime. They can hold values that define different aspects of our application’s environment like database credentials, API endpoints, and even settings for third-party services.

There are three types of environment variables in Next.js: built-in environment variables, public environment variables, and private environment variables. You can access them using process.env.YOUR_VARIABLE. Read on to learn more about how to work with environment variables in Next.js and use them effectively.

Common Use Cases for Environment Variables in Next.js 

API Endpoints

One of the most common use cases for environment variables in Next.js is managing API endpoints. For instance, you might have different API endpoints for your development, staging, and production environments. Instead of hardcoding these into your application, you can use environment variables. This not only makes your code cleaner but also makes it easier to switch between different environments.

Database Connections

Next.js environment variables also come in handy when dealing with database connections. Just like with API endpoints, your database connections may vary depending on the environment and might change from time to time. By using environment variables, you can store your database connection strings and reference them in your application when needed. 

Keep in mind that storing sensitive information like your database username and password in environment variables, while it is more secure than hard coding it into your application, is also not a good practice. Environment variables are stored in plaintext and can be viewed by anyone accessing your environment. Sensitive information should be encrypted and securely stored using secret management or configuration management tools.

Feature Flags

Feature flags are another use case for environment variables. With feature flags, you can enable or disable certain parts of your application based on the environment it’s running in. For instance, you might have a feature that’s still in development and not ready for production. By using an environment variable as a feature flag, you can easily toggle this feature on or off without having to change your code.

Server Configurations

Server configurations are another area where environment variables are invaluable. For instance, you might want to limit the number of requests a user can make to your API in a given timeframe in your production environment. On the other hand, you might want to loosen these restrictions in your development environment to ease testing. With environment variables, you can easily manage these configurations.

Types of Environment Variables in Next.js 

Next.js provides us with three types of environment variables:

Built-in Environment Variables

As the name suggests, these are environment variables provided by Next.js out of the box. They include variables such as NODE_ENV, which tells you the current mode your application is running in (development, production, etc.), and NEXT_PUBLIC_BASE_PATH, which specifies the base path your app is deployed at.

Public Environment Variables

Public environment variables are custom environment variables that you define in your .env file. These variables are accessible both on the server and the client side. They are prefixed with NEXT_PUBLIC_ to indicate that they can be exposed to the browser.

Private Runtime Environment Variables

Private runtime environment variables are only accessible on the server-side and should be used for sensitive data. They are defined in the .env file but without the NEXT_PUBLIC_ prefix.

Accessing Environment Variables in Next.js 

To access the current values of environment variables in Next.js, simply use process.env.YOUR_VARIABLE. For example:

// pages/index.js or pages/page.tsx (if using TypeScript)

export default function Home() {
  return (
    

Hello Next.js!

API Endpoint: {process.env.NEXT_PUBLIC_API_ENDPOINT}

{/* Only server-side environment variables */}

Some Server-Side Variable: {process.env.SOME_SERVER_SIDE_VARIABLE}

); }

The output should look like this:

output next.js environment variables

You can test it by loading the URL in your browser: 

Test next.js environment variables

In this example, NEXT_PUBLIC_API_ENDPOINT is a public environment variable, and SOME_SERVER_SIDE_VARIABLE is a server-side, private environment variable.

Setting Environment Variables in Next.js 

Setting environment variables in Next.js is a two-step process. First, you create a file in the root directory where you’ll store your variables. Next, you load the environment variables during build time and runtime.

Using .env.local, .env.development, and .env.production files

The .env.local file is for storing variables that you want to keep secret and not expose to your version control system. On the other hand, .env.development and .env.production files are for storing variables that change depending on whether you are in development or production mode.

To create these files, navigate to the root directory of your Next.js project and create a new file with the appropriate name. Inside the file, define your variables in the form of NAME=VALUE. Once you’ve done this, you can access your variables in your code using process.env.NAME.

Here are examples of variables set in each of the three env files:

# .env.local
DATABASE_URL=mysecretdatabaseurl

# .env.development
NEXT_PUBLIC_API_ENDPOINT=https://dev.api.example.com

# .env.production
NEXT_PUBLIC_API_ENDPOINT=https://api.example.com

Depending on the environment selected during execution, the relevant environment file is loaded:

the relevant environment file is loaded
next.js api endpoint

Loading Environment Variables During Build Time and Runtime

Next.js automatically loads the environment variables when you start your application. For build time, it reads the variables from your .env files and makes them available in your application. For runtime, it uses the variables defined in your system environment.

To ensure your variables are available during runtime, you need to start your Next.js application with the environment variables defined. This can be done using the env command in the terminal or including them in your start script in the package.json file.

{
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "NEXT_PUBLIC_CUSTOM_VAR=value next start"
  }
}

The output should look like this:

output for package.json

In this example, NEXT_PUBLIC_CUSTOM_VAR is an environment variable explicitly set during runtime. 

You can test it by loading the URL in your browser:

test custom var

Best Practices for Setting and Using Environment Variables in Next.js

Here are best practices that will help you get the most out of environment variables in Next.js.

Differentiate Between Client and Server Variables

Next.js allows you to use environment variables on both the client and server-side. However, it’s essential to remember that any variable you use on the client-side will be exposed to the user.

To differentiate between the two, prefix your server variables with NEXT_PUBLIC_. This way, you can easily tell which variables are safe to use on the client-side and which are not.

Avoid Hardcoding Fallbacks

When you use process.env.YOUR_VARIABLE in your code, there’s a chance that the variable might not be defined. In this case, JavaScript will return undefined.

A common way to handle this is to provide a hardcoded fallback value. However, this is not recommended. Instead, consider using default values in your .env files or handling the undefined case in your application logic.

Leverage Next.js’s Built-in Loading

Next.js automatically loads your environment variables when you start your application. This is a powerful feature that you should leverage.

By relying on Next.js’s built-in loading, you avoid the need to manually load your variables in your code. This reduces the complexity of your application and makes your code cleaner.

Combine with Next.js Config File

Lastly, consider combining your environment variables with the Next.js config file. The Next.js config file is a powerful tool that allows you to customize your build process.

By combining your environment variables with the config file, you can create dynamic settings that change based on your environment. This can be particularly useful for managing different API endpoints or feature flags.

Managing Next.js Environment Variables with Configu

Configu is a configuration management platform comprised of two main components, the stand-alone Orchestrator, which is open source, and the Cloud, which is a SaaS solution:

Configu Orchestrator

As applications become more dynamic and distributed in microservices architectures, configurations are getting more fragmented. They are saved as raw text that is spread across multiple stores, databases, files, git repositories, and third-party tools (a typical company will have five to ten different stores).

The Configu Orchestrator, which is open-source software, is a powerful standalone tool designed to address this challenge by providing configuration orchestration along with Configuration-as-Code (CaC) approach.

Configu Cloud

Configu Cloud is the most innovative store purpose-built for configurations, including environment variables, secrets, and feature flags. It is built based on the Configu configuration-as-code (CaC) approach and can model configurations and wrap them with unique layers, providing collaboration capabilities, visibility into configuration workflows, and security and compliance standardization.

Unlike legacy tools, which treat configurations as unstructured data or key-value pairs, Configu is leading the way with a Configuration-as-Code approach. By modeling configurations, they are treated as first-class citizens in the developers’ code. This makes our solution more robust and reliable and also enables Configu to provide more capabilities, such as visualization, a testing framework, and security abilities.

Learn more about Configu

Try Configu for free
Painless end-to-end configuration management platform
Get Started for Free