Using environment variables in a React application

  • Build time variables: these are variables that are provided when the application is compiled (typically when npm run build is executed). In our example, we’ll pass to the application the git hash of the code when it was built, and an additional arbitrary value.
  • Run time variables: these variables are provided when the application runs, usually these variables differ depending on the environments (development, staging or production). In our example we’ll pass an API URL from the server to the front end application.

Skipping ahead

Build Time Variables

This is documented on the official create-react-app website: https://create-react-app.dev/docs/adding-custom-environment-variables/, but let’s break it down step by step.

Using a .env file

At the root of the project, create a .env file with the following content:

REACT_APP_MY_ENV=Some value
const { REACT_APP_MY_ENV } = process.env;
$ npm i dotenv
// package.json"scripts": {
"start": "node -r dotenv/config src/index.js"
}

Using temporary environment variables

The other way to do this is to use a temporary environment variable. This is convenient when we want to use a dynamic value for the environment variable, such as a date/time or a git hash. In our example, we’ll use the git hash.

// package.json"scripts": {
"start": "REACT_APP_GIT_HASH=\"$(git rev-parse HEAD)\" react-scripts start"
}
const { REACT_APP_GIT_HASH } = process.env;console.log(`Version ${REACT_APP_GIT_HASH}`);
// Version 8e8bd178bd91adb33b7eb5cb1b8220a079a87e65
function MyComponent() {
return <div>{ REACT_APP_GIT_HASH }</div>; // renders the hash
}
$ npm run build
$ serve -s build
// App.js
const { REACT_APP_GIT_HASH, REACT_APP_MY_ENV } = process.env;
console.log(REACT_APP_GIT_HASH); // 8e8bd178bd91adb3.....
console.log(REACT_APP_MY_ENV); // Some value
function App() {
return (
<>
<div>Git Hash: {REACT_APP_GIT_HASH}</div>
<div>My Env: {REACT_APP_MY_ENV}</div>
</>
);
}
  • Prefix the variable name with REACT_APP_
  • The value can be provided it on the command line
    "REACT_APP_MY_VAR=foo react-scripts start"
  • The value can be provided in a .env file
    REACT_APP_OTHER_VAR=wombat
  • Read it from process.env
    const { REACT_APP_MY_VAR, REACT_APP_OTHER_VAR } = process.env;
  • No sensitive information

Runtime Variables

Say we need to provide to our application a value that will change depending where the application runs, like an api url. We can’t read it from the JavaScript application as it is executed on the client. So we’re going to read the variables on the server, and pass them as parameters to the JavaScript application.

// .env
REACT_APP_API_URL=http://localhost:3000/api
const { REACT_APP_API_URL } = process.env;
// public/index.html<body>  //...

<script>
window.API_URL = "\<\%= API_URL \%\>";
</script>
</body>
// backend/index.jsconst express = require('express');
const path = require('path');
const app = express();
const port = 4000;
// where ever the built package is
const buildFolder = '../frontend/build';
// load the value in the server
const { API_URL } = process.env;
// treat the index.html as a template and substitute the value
// at runtime
app.set('views', path.join(__dirname, buildFolder));
app.engine('html', require('ejs').renderFile);
app.use(
'/static',
express.static(path.join(__dirname, `${buildFolder}/static`)),
);
app.get('/', function(req, res) {
res.render('index.html', { API_URL });
});
app.listen(port, () => console.log(`Example app listening on port ${port}!`));
API_URL=https://myserver/api
// App.jsconst API_URL = NODE_ENV === 'development' ? process.env.REACT_APP_API_URL : window.API_URL;
$ cd frontend
$ npm start
$ open http://localhost:3000
Screenshot of home page in development
$ npm run build
$ cd ../backend
$ npm start
$ open http://localhost:4000
Screenshot of home page in production
  • If the file is a ‘config file’ containing constants not likely to change from one server to another or from one build to the next (like a timezone, a locale or specific content, like the site name), then it’s OK to check it in.
  • If the file contains application configuration, like a database password, an API key, any value that needs to change without having to rebuild the application or from server to server, then it’s better not to check it in and use environment variables. Check the dotenv config on how to manage multiple env files.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store