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"
}
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
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
REACT_APP_API_ENDPOINT = https://dev.example.com
REACT_APP_API_ENDPOINT = https://example.com
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
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:
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
If you don't have
serve
installed globally, please do so by runningnpm i -g serve
If you open https://localhost:5000, you will see that endpoint is fetched from .env.production
and logged.
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
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
.env.staging:
REACT_APP_API_ENDPOINT = https://stage.example.com
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"
}
// ...
}
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.
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"
}
}
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"
}
//...
}
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:
Source code
You can view the complete source code here.
Top comments (0)