How to use environment variables in your static webapp/SPA?

Christophe F.
2 min readOct 13, 2021

After finishing a singe page application, you want to deploy it somewhere on the cloud so it can be accessible to your clients. Using Nginx, S3, etc is very convenient, cheap and efficient. There is one main problem using this strategy; you can’t deploy the same build in different environments. For example, if you have a QA environment and production environment, each environment should have custom settings, using different API urls, etc.

Solution 1

One solution is to use .env files. My main problem with this approach is that it will replace the values at build time and not runtime. So you will have to build your app once for QA and once for Prod. This will bring several issues. Your CI/CD pipeline will be slower, what you deploy in prod will be only partially tested in a previous environment.

Solution 2

Another solution would be to use SSR and Node. That way environment variables can be used without any problem, but it will increase cost and complexity for a simple website/app.

Solution 3

Before going into details, the main idea is to generate a file with the custom values, load it in the website/app and then use the values at runtime.

Step 1

Create a new file ‘config.js’ in your ‘public’ folder. Then you can add your custom values:

window.MY_APP_API_URL='https://my-apis.com';                       window.MY_APP_GA='';

You can add as many lines as you need. In this case, I want to be able to use a different API server for each environment, and also enable Google Analytics only in Prod.

Notice the ‘MY_APP’ in the naming. This is important for step #4 later. You can rename with anything you want.

Very important: Do not use it for Auth client secret, database passwords, etc. It will be public. If this is what you need, then use solution 2.

Step 2

Load the configuration file in your app by adding the following line in your ‘public/index.html’ file

<head>
...
<script src='/config.js'></script>
...
</head>

Step 3

You can now use the value in your code, ie:

axios.get(window.MY_APP_API_URL);

Step 4

Now that your local environment is set up and working, you need to be able to customize the ‘config.js’ file per environment. Create a ‘generate_config.sh’ with the following content:

#!/bin/bash -eu# Reset config file
> ./dist/config.js
# Find all the MY_APP_ environment variables in the environment
declare -a customVars
for key in $(env | awk -F "=" '{print $1}' | grep ".*MY_APP_.*")
do
customVars+=($key)
done
# Recreate a new config.js
for key in "${customVars[@]}"
do
echo "window.$key='${!key}';" >> ./dist/config.js
done

This script will read all the environment variables available with the prefix ‘MY_APP’. We don’t want to expose all the variables. You can run this script in your CI/CD or with the ENTRYPOINT if you are using Docker.

The generated ‘config.js’ file will be located in the ‘dist’ folder. Depending on your setup, it might be ‘out’, ‘build’, etc

That’s it. It takes a few minutes to set up but totally worth the effort. Please share any other ideas or improvements in the comments section. Thanks

--

--