Nuxt question
Why are my Nuxt runtimeConfig values empty or undefined in production?
A Nuxt runtimeConfig value stays at its default, often an empty string, in production when no environment variable matches its name. Nuxt overrides a key only from an uppercase variable that starts with NUXT_ and separates key names with underscores: apiSecret is NUXT_API_SECRET, and public.apiBase is NUXT_PUBLIC_API_BASE. A variable named API_SECRET is ignored, and so is a variable for a key that nuxt.config does not declare. The built server also does not read your .env file, so set the variables in the Vercel project and redeploy. Only keys under public reach the browser. Reproduced with nuxt 4.5.2 on 2026-10-31.
Which variable name does my runtimeConfig key need?
The Nuxt docs say a key can be overridden only by an uppercase environment variable that starts with NUXT_, uses _ to separate keys and splits camelCase words. Custom keys must be defined in nuxt.config first. In a run on 2026-10-31 with one build and different variables at start-up, only the NUXT_ names changed the values.
// nuxt.config.ts
runtimeConfig: {
apiSecret: '',
public: { apiBase: '' }
}
# environment at start-up /api/cfg returned
API_SECRET=abc apiSecret: ""
NUXT_API_SECRET=abc apiSecret: "abc"
NUXT_PUBLIC_API_BASE=https://x.test apiBase: "https://x.test"
NUXT_STRIPE_KEY=sk (no stripeKey key) stripeKey: not presentWhy is my .env file ignored in production?
The Nuxt docs say that when you run the built server, your .env file is not read. In the same run, a .env file next to .output with NUXT_API_SECRET=fromdotenv left apiSecret empty when the variable was not set in the process. On Vercel the values come from the project's Environment Variables settings: each variable applies to the environments you select, and Vercel says a change applies only to new deployments.
Why is a runtimeConfig key undefined in the browser?
Keys outside public are available only on the server. In the run above, the page HTML contained the public value once and the private value zero times. If client code needs the value, declare it under public and set the NUXT_PUBLIC_ variable. Do not move a secret there to make an error go away, because every visitor can read public config.
Checklist
How to fix it, then check the fix
- 01List every place the app reads configuration, including values passed through process.env:
grep -rnE "process\.env|useRuntimeConfig|runtimeConfig" --include=*.ts --include=*.vue --include=*.js --exclude-dir=node_modules --exclude-dir=.nuxt --exclude-dir=.output . - 02Declare each key in runtimeConfig in nuxt.config.ts: server-only keys at the top level, keys the browser needs under public.
- 03Name each variable from its key path and add it in Vercel for the environments that run the app:
vercel env add NUXT_API_SECRET production vercel env add NUXT_API_SECRET preview vercel env add NUXT_PUBLIC_API_BASE production - 04Redeploy, because Vercel applies changed variables only to new deployments.
- 05Add a temporary server route that returns booleans, not values, such as { hasSecret: !!useRuntimeConfig(event).apiSecret }, open it on the deployment, then delete it.
Related
Related guides
Sources
Official docs behind this checklist
Browse all launch guides · Read resources · How to make and check your next change
FAQ
FAQ for builders before launch
Can I change a runtimeConfig value without a new build?
The Nuxt docs say runtime config values are replaced by matching environment variables at runtime, and in the run above one build returned different values for different start-up variables. On Vercel the new value still needs a new deployment to take effect.
Does process.env work instead of useRuntimeConfig?
In the Node server run, process.env.API_SECRET read in a server route returned the value while useRuntimeConfig().apiSecret stayed empty, so the two do not follow the same rule. Pick one per value and keep browser values in public config.