Reference
Env var playbook
Deciding where a value goes, the recipes for changing it, and what to check when it comes back undefined. Taught in Lessons 3, 4 and 5.
1 · Decide
| The value is… | Name | Type | How to add it |
|---|---|---|---|
| Public by design (app name, analytics ID) | NEXT_PUBLIC_… | Config | --value on the command line is fine |
| Server setting, not secret (model name, feature flag) | no prefix | Config | --no-sensitive |
| API key or token | no prefix, ever | Secret in Production and Preview; a separate key in Development | Paste at the prompt. Never --value, never echo … | |
| Database credentials | whatever the provider sets | Injected | vercel install <provider>; do not copy by hand |
2 · The three rules
- Scope. A variable applies to the environments you select: Production, Preview, Development. One name can hold a different value in each.
- New deployments only. A change reaches a deployment only when that deployment is created. After any change, redeploy.
- Prefix means public.
NEXT_PUBLIC_values are inlined into browser JavaScript at build time. Everything else is server-only, and is still exposed if your server code returns or renders it.
3 · Recipes
Add a secret
vercel env add ANTHROPIC_API_KEY production
vercel env add ANTHROPIC_API_KEY preview
vercel env add ANTHROPIC_API_KEY development
Paste the production key for the first two and a separate dev key for the third. Then vercel env pull, and push or redeploy.
Add a public or non-secret value
vercel env add NEXT_PUBLIC_APP_NAME production --value "Beachhead" --no-sensitive --yes
Change a value
vercel env update NAME production
Then redeploy: dashboard → Deployments → ⋯ on the latest production deployment → Redeploy.
Rotate a leaked key without downtime
- Create a new key at the provider. Leave the old one active.
vercel env update NAME production, and again forpreview. Paste the new key.- Redeploy production. Redeploy any preview you still need.
- Check the new deployment works (
/api/health, then the real feature). - Revoke the old key at the provider.
If the leak was your laptop key, the same steps apply to development, followed by vercel env pull. Source: Rotating environment variables.
Remove
vercel env rm NAME production
Refresh your laptop
vercel env pull
Writes Development values to .env.local. Variables that exist only in your local file are kept. Restart npm run dev afterwards.
4 · “It's undefined in production”
Work down the list; stop at the first one that is true.
- Not set for that environment. Run
vercel env ls production. A variable added only for Development does not exist in Production. - Set after the deployment was created. Redeploy.
- Name mismatch. Names are case-sensitive. Compare the code with the list character for character.
- Stray whitespace in the value. A copied key with a trailing space or line break is a different key. Update it.
- Read in the browser without the prefix. Client components only see
NEXT_PUBLIC_names. If the value is a secret, move the code to a Route Handler instead of adding the prefix. - Looked up dynamically.
process.env[name]is not inlined for the browser. Writeprocess.env.NEXT_PUBLIC_Xin full. - A branch-specific preview value is overriding it. Run
vercel env ls preview <branch>to see what that branch gets.
The /api/health probe from Lesson 2 answers the first two in one request.
5 · Facts worth having to hand
| Storage | Values are encrypted at rest. Config values are “visible to any user that has access to the project.” |
|---|---|
| Size | 64 KB total per deployment across all variables. 5 KB per variable for the edge runtime. |
| Build logs | A Secret value of 32 characters or more that appears in a build log is replaced with [REDACTED]. |
| Secrets | Production and Preview only. To turn an existing variable into a Secret, remove it and add it again, or run vercel env update NAME --sensitive. |
| Preview branches | A value set for one Git branch overrides the general Preview value of the same name. |
Sources: Environment variables, Sensitive environment variables.
6 · Next.js load order (local)
Next.js looks for a variable in these places and stops at the first hit:
process.env(already set in the shell).env.$(NODE_ENV).local.env.local(skipped whenNODE_ENVistest).env.$(NODE_ENV).env
Source: Next.js: environment variable load order.
7 · Variables Vercel sets for you
| Name | Value |
|---|---|
VERCEL_ENV | production, preview or development |
VERCEL_URL | This deployment's generated domain, without https:// |
VERCEL_BRANCH_URL | The generated domain for the Git branch |
VERCEL_PROJECT_PRODUCTION_URL | The project's production domain; set even in previews |
VERCEL_GIT_COMMIT_SHA | The commit this deployment was built from |
In deployments, Next.js also gets browser-visible copies such as NEXT_PUBLIC_VERCEL_ENV. Those prefixed copies are not created when you pull variables to your laptop. Sources: system and framework environment variables.