TL;DR
- Vercel has three environments: Production, Preview, and Development.
- Add variables in the dashboard under Project → Settings → Environment Variables, or via
vercel env add. - Pull variables to a local
.env.localwithvercel env pull. - Prefix client-side variables with
NEXT_PUBLIC_in Next.js.
The three Vercel environments
Every variable you add is scoped to one or more environments:
- Production — applies to deployments from your production branch (usually
main). Use for live API keys, payment credentials, and production database URLs. - Preview — applies to all other branch deployments and pull request previews. Use test/sandbox credentials here.
- Development — only used when you run
vercel env pullto populate a local.env.local. The file is gitignored by default.
You can assign the same variable name to different values across environments. Vercel injects the correct value automatically based on the deployment context.
Adding variables in the dashboard
- Open your project on vercel.com.
- Go to Settings → Environment Variables.
- Enter the key, value, and select which environments it applies to.
- Click Save. The variable is available on the next deployment.
Changes to environment variables do not redeploy your project automatically. You must trigger a new deployment (push a commit, or click Redeployin the dashboard) for the new values to take effect.
Adding variables via the Vercel CLI
# Add a variable interactively
vercel env add DATABASE_URL
# Add to a specific environment
vercel env add DATABASE_URL production
# List all variables
vercel env ls
# Remove a variable
vercel env rm DATABASE_URL productionPulling variables to your local machine
vercel env pull downloads your Development environment variables into a local .env.local file:
vercel env pull .env.local.env.local is gitignored by Next.js and most frameworks by default. Never commit it. Run vercel env pull again whenever a teammate adds or changes a variable.
Sensitive vs non-sensitive variables
Vercel supports Sensitive variables (encrypted at rest, values hidden in the dashboard after saving) and regular variables. Mark anything that is a secret, key, or credential as Sensitive. Regular variables are fine for non-secret config like NEXT_PUBLIC_SITE_URL.
NEXT_PUBLIC_ prefix
Variables without the NEXT_PUBLIC_ prefix are server-only. They are available in API routes, server components, and server actions, but not in client components or the browser.
Add the prefix for anything the browser needs — analytics IDs, public API endpoints, feature flags. Never prefix secrets.
# Server-only (safe for secrets)
DATABASE_URL=postgres://...
STRIPE_SECRET_KEY=sk_live_...
# Client-accessible (never put secrets here)
NEXT_PUBLIC_SITE_URL=https://myapp.com
NEXT_PUBLIC_STRIPE_KEY=pk_live_...Using env variables in Next.js App Router
// Server component or API route
const db = process.env.DATABASE_URL;
// Client component (NEXT_PUBLIC_ only)
const url = process.env.NEXT_PUBLIC_SITE_URL;Non-prefixed variables accessed in a client component will be undefined at runtime — Next.js strips them at build time for security.
Team and monorepo setups
For monorepos, Vercel lets you scope variables to a specific root directory. You can also share variables across projects using Vercel's Shared Environment Variables (available on Pro and Enterprise), so a single source of truth drives multiple projects.
Rotating a production secret
- Generate a new secret value.
- Add the new value in Settings → Environment Variables (overwrite the old one).
- Redeploy the project.
- Revoke the old value in the issuing service (Stripe, Supabase, etc.).
The old value stays live until the redeployment completes — keep the window short. For zero-downtime rotation, add the new secret under a temporary name, update the code to use it, deploy, then remove the old variable.