@heroku/env-as-html-data
v2.1.0
Published
Inject environment variables into HTML pages as data-* attributes.
Maintainers
Keywords
Readme
Javascript Module to Inject Environment Variables as HTML Data Attributes
Supports local development of Front-end Web JavaScript apps, providing the same runtime configuration strategy as the buildpacks/static web server, without requiring the local CNB pack build and docker run workflow for runtime configuration.
This module injects the current environment variables as HTML data-* global attributes into the app's HTML files. These variables can be updated every time the app starts.
HTML files are parsed and serialized while updating the <head> element. This can normalize invalid HTML and reformat the document.
Using this Module
The general strategy to use this module in a JavaScript web app is to invoke it as part of the build process or immediately before dev-server start-up.
Install to the JavaScript project:
npm install @heroku/env-as-html-data@">= 2.0.0"Configure the target HTML files in the app's project.toml, using the same settings as heroku/static-web-server:
[com.heroku.static-web-server]
root = "public"
index = "index.html"
[com.heroku.static-web-server.runtime_config]
html_files = ["index.html", "subsection/index.html"]By default, the module rewrites the configured index document, or public/index.html when no project.toml settings are present. Paths in html_files are relative to root and may include * or ** glob patterns.
Invoking env-to-html-data
Invoke it before starting a local development server or as part of a build command:
npx @heroku/env-as-html-dataOr invoke it programmatically:
const { injectEnvToHtmlFiles } = require('@heroku/env-as-html-data');
await injectEnvToHtmlFiles(process.env, process.cwd());Using Runtime Environment Variables
Do not set secret values into these environment variables. They will be injected into the website, where anyone on the internet can see the values. As a precaution, only environment variables prefixed with PUBLIC_WEB_ prefix will be exposed.
Use uppercase PUBLIC_WEB_ environment-variable names and access their HTML data attributes in lowercase. Although environment variables are colloquially uppercased, the resulting HTML data attributes are set and accessed in lowercase because they are case-insensitive XML names.
For example, if this app is started:
export PUBLIC_WEB_API_URL=https://api.example.com
export PUBLIC_WEB_RELEASE_VERSION=v42
export PORT=3000
npm startWhen the app is loaded in the web browser's JavaScript environment, these can be accessed using the HTML data attributes:
const head = document.head
// These contain the env vars' values
head.dataset.public_web_api_url
head.dataset.public_web_release_version
// PORT is not set, because it isn't prefixed with PUBLIC_WEB_
head.dataset.port == nullUsing Build-time Variables
Environment variables used to configure the build, such as Webpack configuration, should be accessed using the normal Node.js process.env object.
Development
This is an npm workspace in this repository. It requires Node.js 20 or later, Rust, the wasm32-unknown-unknown Rust target, and wasm-pack 0.15.0.
Install workspace dependencies from the repository root:
npm installInstall the WebAssembly toolchain if needed:
rustup target add wasm32-unknown-unknown
cargo install wasm-pack --version 0.15.0 --lockedBuild the Node.js WebAssembly package:
npm run build --workspace @heroku/env-as-html-dataThe generated Node.js binding and .wasm module are placed in pkg/ and are intentionally not committed. Run the package tests and inspect publish contents with:
npm test --workspace @heroku/env-as-html-data
npm pack --dry-run --workspace @heroku/env-as-html-dataThe repository CI job performs the same Node package verification, plus:
cargo check -p env_as_html_data_wasm --target wasm32-unknown-unknown --lockedRelease
- Update the version in
npm version X.Y.Z --workspace @heroku/env-as-html-data. - Commit this change (and push it to origin)
- Build the package:
npm run build --workspace @heroku/env-as-html-data - Publish:
npm publish --workspaces --access public --otp=XXXXXX- include
--tag nextif a pre-release.
- include
How does the runtime variable injection work?
When injection is invoked:
- reads all
PUBLIC_WEB_*environment variables - reads
project.tomlto determine the document root and target HTML files - rewrites the HTML files, injecting these env vars as
<head data-*>attributes.
Breaking Changes in v2.0
Version 2.0 of this module closely aligns its behavior with the implementation in heroku/static-web-server.
- reads its own configuration from
project.toml(instead ofENV_AS_HTML_DATA_env vars) - reads env vars with
PUBLIC_WEB_prefix (instead ofPUBLIC_) - writes HTML Data attributes to
<head>element (instead of<body>) - safely rewrites HTML files.
All of this ensures that v2 behavior matches the Runtime Configuration behavior of heroku/static-web-server CNB, supporting local app dev without needing to run the full pack build and docker run CNB lifecycle.
