env.dev

Vercel Environment Variables: Dashboard, CLI & Edge

How to configure environment variables on Vercel. Covers the dashboard, CLI (vercel env pull), system variables, per-environment settings, and Edge function access.

Last updated:

Vercel environment variables control how your application behaves across production, preview, and development environments. They are configured through the Vercel dashboard or CLI, injected at build time and runtime depending on the framework, and scoped per environment to prevent accidental leaks. Vercel supports both plaintext and sensitive (encrypted) variables, integrates with external secret managers, and automatically exposes system variables like VERCEL_URL and VERCEL_ENV. Misunderstanding which variables are available in which environment is the single most common deployment issue on the platform. This guide covers every aspect of managing environment variables on Vercel, from dashboard configuration to CLI workflows, framework-specific behavior, and edge function support.

How do you set environment variables in the Vercel dashboard?

Open your project in the Vercel dashboard, navigate to Settings → Environment Variables, and add key-value pairs. Each variable can be scoped to one or more of three environments: Production, Preview, and Development. You can also assign a variable to all three at once.

Variables set in the dashboard are encrypted at rest and only decrypted during the build process or at runtime. After adding or updating a variable, you must redeploy for the change to take effect in production or preview. Development variables are pulled to your local machine using the Vercel CLI.

text
Vercel Dashboard → Project → Settings → Environment Variables

┌──────────────────────┬──────────────────────────┬─────────────────────────┐
│ Key                  │ Value                    │ Environments            │
├──────────────────────┼──────────────────────────┼─────────────────────────┤
│ DATABASE_URL         │ postgres://prod:5432/app │ Production              │
│ DATABASE_URL         │ postgres://stg:5432/app  │ Preview                 │
│ NEXT_PUBLIC_API_URL  │ https://api.example.com  │ Production, Preview     │
│ STRIPE_SECRET_KEY    │ sk_live_abc123           │ Production              │
│ STRIPE_SECRET_KEY    │ sk_test_xyz789           │ Preview, Development    │
└──────────────────────┴──────────────────────────┴─────────────────────────┘

You can define the same key with different values per environment. This is the recommended way to manage environment-specific configuration such as separate database URLs for production and preview branches.

What are the three environment types on Vercel?

Vercel scopes every deployment to one of three environments, and variables are injected accordingly:

  • Production — triggered by pushes to your production branch (usually main). Only variables scoped to Production are injected.
  • Preview — triggered by pushes to any non-production branch or pull requests. Preview-scoped variables are injected. You can further restrict preview variables to specific Git branches.
  • Development — used exclusively for local development via vercel dev or vercel env pull. These variables never reach deployed environments.

A variable scoped only to Production will be undefined in preview deployments. This is the most frequent cause of "works in production but breaks in preview" issues.

What system environment variables does Vercel provide?

Vercel automatically injects system environment variables into every deployment. You must enable them in your project settings under Settings → Environment Variables → System Environment Variables. Once enabled, these are available at build time and runtime:

bash
# Automatically set by Vercel (examples)
VERCEL=1                                   # Always "1" on Vercel
VERCEL_ENV=production                      # "production", "preview", or "development"
VERCEL_URL=my-app-abc123.vercel.app        # Deployment URL (no protocol)
VERCEL_BRANCH_URL=my-app-git-feat.vercel.app  # Branch-specific URL
VERCEL_PROJECT_PRODUCTION_URL=my-app.vercel.app  # Production domain
VERCEL_GIT_COMMIT_SHA=a1b2c3d4            # Full commit SHA
VERCEL_GIT_COMMIT_MESSAGE="fix: update deps"  # Commit message
VERCEL_GIT_COMMIT_AUTHOR_LOGIN=octocat    # Git author
VERCEL_GIT_REPO_SLUG=my-app               # Repository name
VERCEL_GIT_PROVIDER=github                 # "github", "gitlab", or "bitbucket"

Important: VERCEL_URL does not include the protocol. Always prefix it with https:// when constructing absolute URLs. Also note that VERCEL_URL points to the unique deployment URL, not your custom domain. Use VERCEL_PROJECT_PRODUCTION_URL for the canonical production domain.

How do you manage environment variables with the Vercel CLI?

The Vercel CLI provides commands to add, list, remove, and pull environment variables without opening the dashboard. This is useful for scripting and team onboarding workflows.

bash
# Pull all Development-scoped variables to .env.local
vercel env pull .env.local

# Add a new variable interactively
vercel env add DATABASE_URL

# Add a variable non-interactively (pipe the value)
echo "postgres://prod:5432/app" | vercel env add DATABASE_URL production

# List all environment variables
vercel env ls

# Remove a variable from a specific environment
vercel env rm DATABASE_URL production

The vercel env pull command downloads Development-scoped variables and writes them to .env.local by default. This file is automatically git-ignored. After pulling, restart your dev server for the variables to take effect.

How should you use .env.local for local development?

For local development, Vercel recommends .env.local as the primary file for environment variables. Most frameworks (Next.js, Nuxt, SvelteKit, Vite) load this file automatically and it is git-ignored by default.

ini
# .env.local — pulled via "vercel env pull" or created manually
# This file is git-ignored and should never be committed

DATABASE_URL=postgres://localhost:5432/myapp_dev
NEXT_PUBLIC_API_URL=http://localhost:3001
STRIPE_SECRET_KEY=sk_test_xyz789
REDIS_URL=redis://localhost:6379

You can validate your local .env.local file using our env validator to check for syntax errors, missing quotes, or accidental whitespace before deploying.

What is the difference between sensitive and non-sensitive variables?

Vercel classifies environment variables as either Sensitive or non-sensitive. When you mark a variable as Sensitive in the dashboard, its value is write-only: it cannot be read back through the dashboard or CLI after creation. Sensitive variables are decrypted only at build time or runtime and are never exposed in logs or API responses.

  • Non-sensitive: readable in the dashboard, visible in vercel env ls, and included in vercel env pull output.
  • Sensitive: write-only after creation, excluded from vercel env pull, never shown in the dashboard. Ideal for API keys, database passwords, and signing secrets.

Sensitive variables marked with NEXT_PUBLIC_ or similar client-side prefixes will still be inlined into the browser bundle at build time. Marking a client-exposed variable as Sensitive does not prevent it from reaching the browser.

How do frameworks handle environment variables on Vercel?

Vercel detects your framework and applies framework-specific handling for environment variables. The key difference is which prefix, if any, controls client-side exposure:

FrameworkClient PrefixInlining
Next.jsNEXT_PUBLIC_Build time (static replacement)
Vite / SvelteKitVITE_Build time (via import.meta.env)
NuxtNUXT_PUBLIC_Build time + runtime config
Create React AppREACT_APP_Build time (static replacement)
AstroPUBLIC_Build time

Because client-side variables are inlined at build time, changing them requires a redeployment. Server-side variables without the prefix are available at runtime through process.env in serverless functions and API routes. For a deep dive into Next.js-specific behavior, see our Next.js env vars guide.

How do environment variables work in Edge Functions?

Vercel Edge Functions run on the Edge Runtime, which does not provide the Node.js process.env object. Instead, environment variables are injected via process.env as a polyfill that Vercel provides at the edge. This means environment variables work the same way syntactically, but there are important differences:

  • All environment variables are available — there is no restriction on which variables Edge Functions can access.
  • Variables are injected at deploy time, not loaded from the filesystem. There are no .env files at the edge.
  • Dynamic access patterns like process.env[dynamicKey] work because Vercel injects the full environment object, unlike the static replacement used for client-side bundles.
typescript
// app/api/edge-example/route.ts
export const runtime = 'edge';

export function GET() {
  // process.env works in Edge Functions via Vercel's polyfill
  const apiKey = process.env.API_SECRET_KEY;
  const region = process.env.VERCEL_REGION; // System variable

  return new Response(JSON.stringify({ region }), {
    headers: { 'content-type': 'application/json' },
  });
}

What are the most common environment variable issues on Vercel?

These are the issues that account for the majority of Vercel deployment debugging time:

  • Variable not available in preview: the variable is scoped only to Production. Add the Preview environment scope in the dashboard.
  • Variable undefined after update: environment variable changes require a redeployment. Vercel does not hot-reload variables into existing deployments. If a freshly redeployed app still reports the variable as undefined, see dotenv not loading for the full debugging checklist.
  • Case sensitivity: environment variable names are case-sensitive on Vercel. DATABASE_URL and database_url are treated as different variables.
  • Client-side variable is undefined: forgot the framework prefix (NEXT_PUBLIC_, VITE_, etc.) or accessed the variable at runtime instead of build time.
  • Multiline values: the Vercel dashboard supports multiline values (paste directly), but the CLI requires proper escaping. Use quotes and newlines carefully.
  • Variable size limits: individual variable values are capped at 64 KB. Total environment size across all variables cannot exceed 64 KB per deployment, and Edge Functions cap each variable at 5 KB.

How do you integrate Vercel with external secret managers?

For teams with strict security requirements, Vercel supports integrations with external secret management services. These integrations sync secrets from your provider into Vercel environment variables automatically. If you need to share these secrets across teams without committing them to Git, see our guide on sharing env files securely.

  • Vercel Integrations marketplace: native integrations exist for HashiCorp Vault, Doppler, 1Password, and AWS Parameter Store. Install from the Integrations tab in your project settings.
  • Doppler: automatically syncs secrets to Vercel on every change. Supports environment mapping (Doppler environments to Vercel Production/Preview/Development).
  • HashiCorp Vault: use the Vercel integration or a build-time script that fetches secrets from Vault and injects them as build environment variables.
  • Runtime fetching: for secrets that must not exist as environment variables at all, fetch them at runtime from AWS Secrets Manager, GCP Secret Manager, or Azure Key Vault directly in your serverless function.
typescript
// Example: fetching secrets at runtime from AWS Secrets Manager
import { SecretsManagerClient, GetSecretValueCommand } from '@aws-sdk/client-secrets-manager';

const client = new SecretsManagerClient({ region: 'us-east-1' });

export async function getSecret(secretId: string): Promise<string> {
  const command = new GetSecretValueCommand({ SecretId: secretId });
  const response = await client.send(command);
  return response.SecretString ?? '';
}

// Usage in an API route
export async function GET() {
  const dbUrl = await getSecret('prod/database-url');
  // Use dbUrl to connect to the database
}

Runtime secret fetching adds latency to cold starts but ensures secrets are never stored in Vercel's infrastructure. For most applications, Vercel's built-in Sensitive variables combined with a sync integration provide the best balance of security and performance.

References

Was this helpful?

Read next

Next.js Environment Variables: Complete Guide

How Next.js handles environment variables: .env file load order, NEXT_PUBLIC_ prefix, server vs client access, and common production errors.

Continue →

Frequently Asked Questions

How do I set environment variables on Vercel?

Go to Project Settings > Environment Variables in the Vercel dashboard. Add each variable with its value and select which environments it applies to: Production, Preview, Development, or all three.

Why are my environment variables not working in Vercel preview deployments?

Check that the variable is enabled for the Preview environment in your Vercel project settings. Also ensure you are using the correct branch scope if you have branch-specific overrides configured.

What is VERCEL_URL?

VERCEL_URL is a system environment variable that contains the deployment URL (without the protocol). It changes for every deployment. Use it to construct absolute URLs in your application, but prefer NEXT_PUBLIC_VERCEL_URL for client-side access in Next.js.

What is the size limit for Vercel environment variables?

Vercel allows a total of 64 KB of environment variables per deployment across all variables combined, with no single variable exceeding 64 KB. Edge Functions and Middleware using the edge runtime are limited to 5 KB per individual environment variable.

Can I sync secrets from 1Password or Doppler to Vercel?

Yes. The Vercel Integrations marketplace has native integrations for 1Password, Doppler, HashiCorp Vault, and AWS Parameter Store. Install one from your project settings under the Integrations tab, and secrets sync to Vercel environment variables automatically on every change.

Stay up to date

Get notified about new guides, tools, and cheatsheets.