DEV Community

loading...
Cover image for Setting Multiple Environment Variables in React

Setting Multiple Environment Variables in React

collegewap
Originally published at codingdeft.com ・4 min read

You might have come across instances where you would want to use a certain value in the development environment and
another value in the production environment,
say for instance there is an API endpoint from which you fetch a list of users.
Now definitely you will have a different URL for each of the environments, such that development data is not fetched in production.

To identify which environment we are in, we can make use of a special environment variable: process.env.NODE_ENV.
When you are using Create React App,
the react-scripts will set the value of NODE_ENV to development when npm start is executed and
to production when you run npm run build.

So you can make use of NODE_ENV to determine which environment you are in and
set the value of API endpoint accordingly as shown in the below code snippet

let API_ENDPOINT
if (process.env.NODE_ENV === "production") {
  API_ENDPOINT = "https://example.com"
} else {
  API_ENDPOINT = "https://dev.example.com"
}
Enter fullscreen mode Exit fullscreen mode

However, the problem with the above approach would be that we will have to put this check wherever we would want to use the environment-specific values and
if we would want to add an environment or change value for a particular environment,
we will have to scan through the whole codebase, which is a cumbersome task.

To solve this problem, React ships with .env file support.
That is, we can have a file named .env at the root directory of our project and have the values defined there.
Let's see how we can implement it in the next steps.

Project Setup

First of all, let's create a new react project using the below command:

npx create-react-app environment-variables
Enter fullscreen mode Exit fullscreen mode

Now in the root directory create 3 files .env, .env.development and .env.production with the following content:

REACT_APP_API_ENDPOINT = https://default.example.com
Enter fullscreen mode Exit fullscreen mode
REACT_APP_API_ENDPOINT = https://dev.example.com
Enter fullscreen mode Exit fullscreen mode
REACT_APP_API_ENDPOINT = https://example.com
Enter fullscreen mode Exit fullscreen mode

Update App.js with the following code:

function App() {
  console.log({ REACT_APP_API_ENDPOINT: process.env.REACT_APP_API_ENDPOINT })
  return <div>Home</div>
}

export default App
Enter fullscreen mode Exit fullscreen mode

In the above code, we are logging the value of process.env.REACT_APP_API_ENDPOINT,
which means any value stored inside .env files can be accessed via process.env.

Create React App requires all the environment variables to begin with REACT_APP_, any other variables will be ignored.
This is done to avoid developers from accidentally committing any environment variables that may contain app secrets.

Now let's start the application using npm start and see what is logged in the browser console:

Endpoint Log start

From this, we can understand that whenever npm start is run, NODE_ENV will be set to development and
environment variables will be fetched from .env.development

Now let's build the application using npm run build and try running the application using the below command:

serve -s build
Enter fullscreen mode Exit fullscreen mode

If you don't have serve installed globally, please do so by running npm i -g serve

If you open https://localhost:5000, you will see that endpoint is fetched from .env.production and logged.

Endpoint Log build

CRA Documentation says that you cannot override NODE_ENV manually.
So if you want to have 2 more environments, say qa and staging then you cannot override NODE_ENV and expect it to work.

Having multiple environments

To support multiple environments, we need to install an additional library and modify the build scripts slightly.
Let's install env-cmd, as a development dependency using the following command.

npm i -D env-cmd
Enter fullscreen mode Exit fullscreen mode

env-cmd helps in specifying which particular .env file to consider while building the application.

So now let's add .env files for qa and staging environments:
.env.qa:

REACT_APP_API_ENDPOINT = https://qa.example.com
Enter fullscreen mode Exit fullscreen mode

.env.staging:

REACT_APP_API_ENDPOINT = https://stage.example.com
Enter fullscreen mode Exit fullscreen mode

And add couple of build scripts to package.json

{
  // ...
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "build:qa": "env-cmd -f .env.qa npm run-script build",
    "build:staging": "env-cmd -f .env.staging npm run-script build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  }

  // ...
}
Enter fullscreen mode Exit fullscreen mode

So now if you run npm run build:qa or npm run build:staging, and serve the application,
you will see the respective endpoint URL being logged.

Endpoint Log qa

Endpoint Log staging

Keeping all the configuration in one file

If you don't like having a separate file for each environment, you can store all the configurations in one file!

Create a file named .env-cmdrc in the root directory of the project with the following content:

{
  "development": {
    "REACT_APP_API_ENDPOINT": "https://devapi.example.com"
  },
  "qa": {
    "REACT_APP_API_ENDPOINT": "https://qaapi.example.com"
  },
  "staging": {
    "REACT_APP_API_ENDPOINT": "https://stagingapi.example.com"
  },
  "production": {
    "REACT_APP_API_ENDPOINT": "https://prodapi.example.com"
  }
}
Enter fullscreen mode Exit fullscreen mode

Now add few scripts to package.json to read the variables from the above file:

{
  //...
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "build:dev": "env-cmd -f .env.development npm run-script build",
    "build:qa": "env-cmd -f .env.qa npm run-script build",
    "build:staging": "env-cmd -f .env.staging npm run-script build",
    "build-dev": "env-cmd -e development npm run-script build",
    "build-qa": "env-cmd -e qa npm run-script build",
    "build-staging": "env-cmd -e staging npm run-script build",
    "build-prod": "env-cmd -e production npm run-script build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  }
  //...
}
Enter fullscreen mode Exit fullscreen mode

Now build the development code using the command npm run build-dev, run the built code using serve -s build,
and you will see the correct API URL being printed:

Endpoint Log dev

Source code

You can view the complete source code here.

Discussion (0)