Using environment variables in React

When you don’t have a server-side programming background, environment variables can seem like a bit of magic. That lack of knowledge smacks you in the face like a bag of dicks when you’re done creating todo applications on your localhost, and try to create a production build for the first time.

Update: If you want to know how to use environment variables in your own custom tooling or a deep dive in how environment variables work in React, you can keep reading this wonderful piece of poetry. But if you’re looking for a quick fix and you’re using an out of the box Create React App, check documentation here. NextJS users, check documentation here.

The problem we’re solving:

How to declare different API url’s for your local development build and production build

In short: environment variables

Actually setting and using the environment variables

Method 1: Using npm scripts to set environment variables

Go to your package.json, check the scripts key and look for the command(s) that run webpack. It’ll probably look something similar like this:

The double dashed commands are webpack cli commands

Let’s add some environment variables with a --env flag in our scripts.

Notice the --env flag in both scripts

We’ve added the --env.API_URL= part in both scripts. Now, run your npm run dev command, go to your React component and use the process.env.API_URL:

const App = () => <h1>{process.env.API_URL}</h1>;

Aaaand.. I broke your project. Sorry about that.

— That’s because when we use environment variables in our front-end code, they really just serve as placeholders that will be replaced when we compile our code. The problem is, we didn’t tell webpack to compile those variables to real values. Let’s do that in our webpack config file with the DefinePlugin webpack plugin:

DefinePlugin needs you to literally define your “environment variables” by setting a hard key

You can also reduce the values to a nice object, so you won’t have to define them manually:

When you run your command now, everything gets compiled and your process.env.API_URL will be compiled to the correct url, based on your environment variable.

Congratulations! But wait, there’s more!

Method 2: Using an .env file to set environment variables

To prevent people from finding out your local database password is the same one you use for every single one of your accounts on the internet , I urge you to add the .env file to your .gitignore.

Your front-end code will refer to the same environment variable (process.env.API_URL) on both environments (development/production), but because you defined different values in your .env files, the compiled values will be different.

Let’s create an .env file

API_URL=http://localhost:8000

Is that is? Yes, that’s it..

Handle the .env file

$ npm install --save-dev dotenv

Adding the variables to your React project

In this case, we’re developing client-side. And dotenv needs some sort of environment to actually store the variables. Webpack to the rescue!

That whole webpackDefinePlugin stuff was working pretty well earlier, so let’s use it again in our webpack configuration:

Check the dotenv github for configuration options in .config()

Calling .config() on dotenv will return an Object with all the environment variables set in your .env file under a key called parsed. Now, let’s check our React code:

const App = () => <h1>{process.env.API_URL}</h1>;

And damn, it works! It shows the value of the API_URL environment variable that you defined in your .env file.

Just one problem: we still need to define different API_URL values for our production and development environment.

Different environment variables for different environments

  • .env (contains all the environment variables for production)
  • .env.development (contains all the environment variables for development)

Just to be clear: we’re postfixing the .env filename with the name of the environment. It’s common practice to use the original .env file for your production build, so we won’t be postfixing that one.

Setting the active environment using NPM scripts

Because we’ve defined our environment in our package.json, we now have it available in our webpack configuration!

The next step is to go to our webpack configuration and let it use the .env file that belongs to our active environment. Just like before, we’re using dotenv, but now we’re specifying a custom path in the parameters.

Getting a bit convoluted there m8

That’s all we’re doing for now, but you could create more .env files for more environments (.env.staging for example), as long as you set the environment in the package.json and create the corresponding .env file in the root of your project!

This last part may be a lot to take in, so go through it line by line and if you have any questions, just comment down below, or on Twitter.

And that wraps it up! You’ve done it!

Great job.

XOXO.

I eat frozen bread like toast.