How to gracefully use environment variables in React app? Let me show you pretty quickly.
I access environment variables through a single source - the assertEnvVar
function. The function will throw an error if there is no such variable.
type VariableName = "SENTRY_KEY" | "API_URL" | "VERSION"
export const assertEnvVar = (name: VariableName): string => {
const envVarName = `REACT_APP_${name}`
const value = process.env[envVarName]
if (!value) {
throw new Error(`Missing ${envVarName} environment variable`)
}
return value
}
The process.env
is an object with environment variables. But we don't want all environment variables in the bundle for the whole world to see. I use create-react-app
, and it will export only variables starting with REACT_APP_
. Different starters and frameworks have different prefixes. For example, Vite will have a VITE_
prefix.
To not misspell the environment variable name, we have a union type instead of a string type for the name argument of the function. Those names do not include the REACT_APP_
prefix, so the keys are shorter. If I change frontend tooling, I would only need to update the prefix in one place instead of going through every function call.
For local development, I declare environment variables in the .env
file. For production, I set them before deploying a new version. You can also set environment variables in a script. I do that to access package.json's
version in the app.
"start": "REACT_APP_VERSION=$npm_package_version react-scripts start"