Dynamic JavaScript and React Configuration
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 process.env
directly into the compiled JavaScript.
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.
There are many approaches to runtime configuration of static JavaScript applications.
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:
- Loading
config.js
before your main bundle introduces latency before you can load your app. - Loading
config.js
alongside 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.
Our Solution
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
pulled from REACT_APP_
, NODE_
, and 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 process.env
into calls to window._jsenv || process.env
. See the GitHub repo for some examples
of how we handle this.
Your index.html
file will be modified to include a <script>
tag inside your <head>
.
It’s safe to call multiple times, and uses Go’s HTML5 parser so should be valid for whatever you throw at it.
Usage
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
Feedback
If you have any suggestions or feedback, please open an issue or get in touch directly.
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!