Limits of Nuxt runtimeConfig public exposure when overriding with environment variables in integration tests
0 reputation · 27 Jul 2021, 10:10 UTC
0 reputation · 27 Jul 2021, 10:10 UTC
Ensure that integration tests run against a local stub server without accidentally exposing production secrets through Nuxt's runtimeConfig.public.
Nuxt treats NUXT_ prefixed variables as private server‑only settings and NUXT_PUBLIC_ prefixed variables as public settings that are serialized to the client bundle. While private values stay on the server, there is no build‑time guard that prevents a secret from being placed under runtimeConfig.public, which would leak it to the browser. Moreover, the exact moment (build‑time vs runtime) at which NUXT_PUBLIC_ overrides are applied can differ between Nuxt major versions and deployment presets (e.g., static, serverless), creating uncertainty about whether a test‑time environment variable will be respected.
35275 reputation · 27 Jul 2021, 12:09 UTC
In a Nuxt 3 project that uses the static preset, NUXT_PUBLIC_ environment variables are resolved during the build step. The value that exists in the environment at the moment nuxt build is executed is baked into the client bundle and cannot be overridden later. Private variables (NUXT_) stay on the server and are never serialized to the bundle.
When a test runner starts a local stub server it usually sets environment variables before invoking nuxt build. If the build is cached, the test‑time variables may be ignored, and a secret that was mistakenly placed under runtimeConfig.public could slip into the bundle. Because Nuxt 3 does not guard against this at build time, developers must explicitly verify that no private keys are present in the public config.
Delete the .nuxt directory or run nuxt clean before each test build to avoid stale env values.
export NUXT_PUBLIC_SECRET=__TEST_SECRET__
nuxt build
Replace __TEST_SECRET__ with a unique marker that would be obvious if leaked.
grep -R "__TEST_SECRET__" dist/client | wc -l
The count must be zero. A non‑zero result indicates the secret was serialized.
Use a small Node script or a Jest matcher that reads the generated app.js (or client.js) and asserts that no string matches a list of known private keys or a regex pattern such as /\bSECRET\b/.
curl http://localhost:3000/api/nuxt-config | jq .runtimeConfig.public
Ensure that private values do not appear in the JSON payload.
Nuxt Bridge (the underlying engine for Nuxt 3) applies NUXT_PUBLIC_ overrides at build time for static sites, whereas Nuxt 2 applies them during server start. Consequently, a test that relies on runtime overrides will work in Nuxt 2 but not in a static Nuxt 3 build. If your test environment mixes these versions, you need to tailor the verification accordingly.
To fine‑tune the recommendation, could you confirm whether your integration tests invoke nuxt build or nuxt dev before spinning up the stub server?
Use comments to ask for clarification. Post a solution as an answer.
35,275 reputation · 27 Jul 2021, 22:03 UTC
When the static preset is used, Nuxt runs nuxt build and then generates a fully static site. During that build step all environment variables that match the NUXT_PUBLIC_ prefix are resolved and merged into runtimeConfig.public. The resulting object is then serialized into the client bundle (accessible via window.__NUXT_PUBLIC__). Any change to process.env.NUXT_PUBLIC_… after the build will not be reflected in the already‑generated pages.
For integration tests that spin up a stub server, this means you must either:
nuxt build with the desired test‑time environment variables before starting the server, orssr or serverless) so that runtimeConfig.public is read at request time.A practical guard is to parse the generated nuxt.config.{js,ts} after the build and assert that runtimeConfig.public contains only the keys you expect to be public. This catches accidental leaks of secrets placed under runtimeConfig.public before the test suite runs.