Changelog v3.16.3 (2026-06-03)
Version 3.16.3 (2026-06-03)
Patch release that lets static-content parsing template environment-variable values into served files, alongside the existing per-user claim templating. This is aimed at Single-Page Apps deployed to Kubernetes: the SPA bundle is built once, and app-wide values (BUILD_LABEL, feature-flag toggles, analytics IDs) are injected from pod env vars at boot without rebuilding the bundle per environment.
What changed
AvailableEnvVars under StaticFiles:ParseContentOptions
A new optional config key lists environment variable names whose values are templated into static content using the same {NAME} tag syntax the claim path already uses:
jsonc
"StaticFiles": {
"Enabled": true,
"ParseContentOptions": {
"Enabled": true,
"FilePaths": [ "/index.html" ],
"AvailableClaims": [ "user_id", "user_name" ],
"AvailableEnvVars": {
"BUILD_LABEL": "local",
"DEMO_FLAG": "false",
"TRACKING_ID": ""
}
}
}html
<script>
window.__appConfig = {
userId: {user_id}, // claim → 123 or null
buildLabel: {BUILD_LABEL}, // env → "demo" (or "local" default)
demoMode: {DEMO_FLAG} === "true"
};
</script>Behaviour details:
- Two forms.
AvailableEnvVarsaccepts an array of names (["BUILD_LABEL"]; a missing variable resolves to the empty string) or an object of name→default pairs ({"DEMO_FLAG":"false"}; the default is used when the variable is absent).AvailableClaimsgains the same object form, so an absent claim can resolve to a configured default instead ofNULL. - Resolved once at startup. Env values are read at parser construction. A K8s pod restart re-reads them; changing a value in a running process is not picked up.
- JSON-escaped, like claims. Each value is substituted as a complete, escaped JSON literal, so templates use a bare
{NAME}token (no surrounding quotes) and an accidental quote/backslash in a value cannot break the JS string. - Claims win on collision. If a name exists both as a user claim and an env var, the per-request claim value takes precedence.
Security note
Anything listed in AvailableEnvVars is templated into static content served to any client — treat it as a public allowlist. Never list a secret (database password, API key, signing token). Resolution is an explicit per-name lookup; the whole environment is never exposed. This is distinct from the server-side Config:ParseEnvironmentVariables mechanism, which substitutes {ENV} tokens into appsettings.json values that never leave the server.
This is fully backward compatible: the new key is optional, and configs that omit it behave exactly as before.