Most of the frontends we build at Lithic are written in React.
Normally we deploy them as static apps in Netlify.
This will write environment variables from
Sometimes, though, we need to dynamically configure the applications based on runtime,
not build time, environment variables. The basic
create-react-app workflow doesn’t work in this situation.
Most of them involve writing out a
config.js file at server boot time,
and having the client load this before or alongside the main JS bundle.
In some solutions, the JS is dynamically templated.
All of these approaches have downsides:
config.jsbefore your main bundle introduces latency before you can load your app.
config.jsalongside your main bundle means your app cannot synchronously access config, which introduces complexity.
- Templating your main bundle on each request is nontrivially complex (we love nginx too but the fewer script callouts the better).
There is a solution, though: template config directly into
index.html at server/container boot time.
We built runtime-js-env
to handle dynamic JS config with no downsides.
It’s a simple Go program that rewrites
index.html to include a
window._jsenv object with your config
HEROKU_ environment variables.
You call it at container/server boot time,
and the only change you need to make in your JS is change calls to
into calls to
window._jsenv || process.env. See the GitHub repo for some examples
of how we handle this.
index.html file will be modified to include a
<script> tag inside your
It’s safe to call multiple times, and uses Go’s HTML5 parser so should be valid for whatever you throw at it.
runtime-js-env is a Go program, so you’ll need Go installed.
$ go get github.com/lithictech/runtime-js-env $ runtime-js-env --help NAME: runtime-js-env - A new cli application USAGE: runtime-js-env [global options] command [command options] [arguments...] COMMANDS: help, h Shows a list of commands or help for one command GLOBAL OPTIONS: --index value, -i value Path to the index.html file. Default to index.html in pwd. (default: "index.html") --window-var-name value, -w value Attribute name for the config object. (default: "_jsenv") --env-prefixes value, -p value Environment variable prefixes to copy into the config object. (default: "REACT_APP_", "NODE_", "HEROKU_") --indent value, -t value Indentation for each line in the config script tag. (default: " ") --help, -h show help (default: false) $ runtime-js-env -i public/index.html
This was originally posted on my consultancy’s blog, at https://lithic.tech/blog/2020-05/react-dynamic-config. If you have any questions, please leave a comment or get in touch!