Vercel Hobby · Beachhead course

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…NameTypeHow 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 prefixConfig--no-sensitive
API key or tokenno prefix, everSecret in Production and Preview; a separate key in DevelopmentPaste at the prompt. Never --value, never echo … |
Database credentialswhatever the provider setsInjectedvercel install <provider>; do not copy by hand

2 · The three rules

  1. Scope. A variable applies to the environments you select: Production, Preview, Development. One name can hold a different value in each.
  2. New deployments only. A change reaches a deployment only when that deployment is created. After any change, redeploy.
  3. 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

  1. Create a new key at the provider. Leave the old one active.
  2. vercel env update NAME production, and again for preview. Paste the new key.
  3. Redeploy production. Redeploy any preview you still need.
  4. Check the new deployment works (/api/health, then the real feature).
  5. 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.

  1. Not set for that environment. Run vercel env ls production. A variable added only for Development does not exist in Production.
  2. Set after the deployment was created. Redeploy.
  3. Name mismatch. Names are case-sensitive. Compare the code with the list character for character.
  4. Stray whitespace in the value. A copied key with a trailing space or line break is a different key. Update it.
  5. 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.
  6. Looked up dynamically. process.env[name] is not inlined for the browser. Write process.env.NEXT_PUBLIC_X in full.
  7. 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

StorageValues are encrypted at rest. Config values are “visible to any user that has access to the project.”
Size64 KB total per deployment across all variables. 5 KB per variable for the edge runtime.
Build logsA Secret value of 32 characters or more that appears in a build log is replaced with [REDACTED].
SecretsProduction 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 branchesA 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:

  1. process.env (already set in the shell)
  2. .env.$(NODE_ENV).local
  3. .env.local (skipped when NODE_ENV is test)
  4. .env.$(NODE_ENV)
  5. .env

Source: Next.js: environment variable load order.

7 · Variables Vercel sets for you

NameValue
VERCEL_ENVproduction, preview or development
VERCEL_URLThis deployment's generated domain, without https://
VERCEL_BRANCH_URLThe generated domain for the Git branch
VERCEL_PROJECT_PRODUCTION_URLThe project's production domain; set even in previews
VERCEL_GIT_COMMIT_SHAThe 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.