Websites

Vercel Preview vs Production Environment Variables Explained

Understand how Vercel Preview, Production, and Development environment variables differ, including branch-specific values, redeploys, and common mistakes.

Ryan Lee9 min read
Vercel Preview vs Production Environment Variables Explained

One of the most confusing deployment problems I ran into was also one of the simplest once I understood it:

the same Vercel project can run with different environment variables depending on whether the deployment is Preview, Production, or Development.

That matters because an application can work perfectly on the live site and fail on a Preview URL even when the code is identical.

The difference may not be the code.

It may be the environment.

This guide explains how I now think about Vercel environment variables and what I check before changing working code.

Quick answer

Vercel separates environment variables by deployment environment.

The standard environments are:

  • Production — the live production deployment
  • Preview — pull requests and non-production Git branches
  • Development — local development configuration

That means a variable can:

  • exist in Production but not Preview
  • have one value in Preview and another in Production
  • be limited to a specific Preview branch
  • work locally but be missing from Vercel entirely

After changing an environment variable, create a new deployment. An existing deployment does not automatically receive the new value.

Preview vs Production at a glance

| Environment | Typical use | Example | | --- | --- | --- | | Production | Live website | Real users and production services | | Preview | Branch or pull-request testing | Feature testing before merge | | Development | Local development | Your local machine |

The distinction sounds small.

It becomes important as soon as your application uses:

  • Supabase
  • authentication
  • API keys
  • external services
  • different databases
  • branch-specific configuration

Why Production can work while Preview fails

Imagine your production app expects:

NEXT_PUBLIC_SUPABASE_URL=...
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=...

Those variables exist in the Vercel Production environment.

The live site works.

Then you create a feature branch.

Vercel builds a Preview deployment.

If the same variables are not available to Preview, the application may suddenly fail.

The code did not necessarily change in the relevant area.

The deployment context changed.

That is why my first question is now:

Which Vercel environment is this deployment actually using?

Production environment variables

Production values are intended for the live production deployment.

For example:

  • production Supabase project URL
  • production API endpoints
  • live analytics configuration
  • public production site URL
  • server-side credentials required by the live app

Production should be treated as the most sensitive environment because it affects real users and real data.

A Preview deployment should not automatically receive every Production secret just because it belongs to the same Vercel project.

Preview environment variables

Preview deployments are commonly created from:

  • pull requests
  • feature branches
  • non-production Git branches

This gives you a safe place to test changes before they reach the live site.

But Preview still needs the configuration required by the feature you are testing.

A Preview deployment may use:

  • the same public API values as Production
  • a separate staging database
  • a Supabase preview branch
  • branch-specific test credentials
  • a different redirect URL strategy

The right choice depends on the project.

The important part is that the choice is intentional.

Development environment variables

Development configuration is for local work.

A common mistake is assuming that because a value exists in .env.local, Vercel also has it.

It does not.

Local environment files and Vercel project settings are separate sources.

A value can therefore work locally while being completely absent from Preview and Production.

When I see:

works on my machine, fails after deployment

environment configuration is one of the first layers I check.

Branch-specific Preview variables

Vercel also supports environment variables scoped to a specific Preview Git branch.

That can be useful when different branches need different test infrastructure.

For example:

feature-auth may use one test backend.

staging may use another.

This gives you more control than assigning one value to every Preview deployment.

It also adds more places where a mismatch can happen.

When debugging, check both:

  • the environment
  • the branch scope

Environment variable names must match the code

Even when the right value exists, the application can still fail if the names do not match.

For example, the project stores:

NEXT_PUBLIC_SUPABASE_ANON_KEY=...

but the current application reads:

process.env.NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY

Both may represent valid public Supabase credentials.

The code is still asking for a name that does not exist.

That is why I compare:

Vercel variable name → application variable name

character by character.

Public and private variables are different security decisions

A Next.js variable beginning with NEXT_PUBLIC_ can be exposed to browser-side code.

That is appropriate for public client configuration such as a Supabase publishable key.

It is not appropriate for privileged credentials.

Never put a secret server credential into a public browser variable simply to make Preview work.

The correct fix is to configure the environment properly, not weaken the security boundary.

You need a new deployment after changing variables

This catches people because the Vercel dashboard may show the new value immediately.

The already-created deployment still represents the configuration it was built with.

After changing a variable:

  1. save the variable
  2. create or trigger a new deployment
  3. wait for the deployment to finish
  4. test the new deployment URL

Do not keep refreshing an older Preview and conclude the fix did not work.

A simple debugging workflow

When a deployment behaves differently from another environment, I check in this order.

1. Identify the failing deployment

Is it:

  • local
  • Preview
  • Production

2. Confirm the branch

Which Git branch created the deployment?

3. Check required variable names

What does the code actually read?

4. Check Vercel scope

Is each required variable available to that environment?

5. Check branch-specific overrides

Does this Preview branch have a different value?

6. Redeploy

Was the deployment created after the variable was changed?

7. Test the real feature

Do not only check that the page renders.

Test the login, API request, form, database query, or integration that depends on the value.

Example with Supabase

This is where I learned the difference most clearly.

A Next.js application might use:

NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=sb_publishable_...

Production may connect to the real Supabase project.

Preview might connect to a staging or preview project.

Or a small project may temporarily use the same public configuration in both.

Whichever model you choose, authentication redirects also need to match the environment.

That is why a Supabase login can work locally but fail after deployment even when the credentials themselves are correct.

I cover that troubleshooting path in Supabase Login Works Locally but Not on Vercel: 8 Fixes.

Preview URLs and authentication

Preview deployments often have generated Vercel URLs.

If the application uses OAuth, magic links, password reset, or email confirmation, the authentication provider needs to know which redirect destinations are allowed.

Supabase supports additional redirect URLs and wildcard patterns for Vercel Preview deployments.

For Production, use the exact production site URL where possible.

For Preview, allow only the patterns you intentionally need.

Environment variables and redirect allow-lists are separate settings.

Both can affect the same login flow.

Vercel system variables can help identify the environment

Vercel provides system environment variables that can help code understand where it is running.

For example, VERCEL_ENV can indicate whether the deployment is:

  • production
  • preview
  • development

Framework-specific public versions are also available where needed.

I do not use environment detection as a substitute for clear configuration.

But it can be useful when an application intentionally behaves differently in Preview and Production.

Common mistakes

Assuming a branch named staging is automatically Production-like

A branch name does not define the Vercel environment by itself.

A non-production branch is typically a Preview deployment unless you intentionally configure another environment strategy.

Copying Production secrets into Preview without thinking

Preview is still a deployed environment and may be accessed by more people than the live site.

Use the minimum credentials required.

Changing a variable and testing an old deployment

Create a new deployment.

Assuming local .env.local values exist in Vercel

They do not unless you configure or sync them.

Debugging application code before checking environment scope

If the same code works elsewhere, compare environment configuration first.

My environment-variable checklist

Before I rewrite code, I verify:

  • [ ] I know whether the failing deployment is Development, Preview, or Production.
  • [ ] I know which branch created it.
  • [ ] Required variable names match the code exactly.
  • [ ] Required variables exist in the correct Vercel environment.
  • [ ] Branch-specific Preview overrides are intentional.
  • [ ] Public variables contain only public client configuration.
  • [ ] Secrets remain server-side.
  • [ ] I created a new deployment after the change.
  • [ ] I am testing the new deployment.
  • [ ] Authentication redirect URLs match the environment.

FAQ

Are Preview and Production environment variables separate in Vercel?

Yes. Vercel allows variables to be configured for different environments, so a value available in Production may not be available in Preview.

Do Preview deployments use Production environment variables?

Not automatically. Configure the values the Preview environment needs.

Can I use different values for different Preview branches?

Yes. Vercel supports branch-specific Preview environment variables.

Why does my app work locally but not on Vercel?

Local environment variables may exist only on your machine. The deployed project may be missing them or using a different value or scope.

Do I need to redeploy after changing a Vercel environment variable?

Yes. Test a new deployment created after the change.

Final thoughts

The most useful thing I learned about Vercel environment variables was not a dashboard trick.

It was a debugging principle.

Same code does not always mean same environment.

Production, Preview, and Development can run the same application with different configuration.

Once I understood that, a whole category of deployment problems became easier to reason about.

If you are currently debugging a specific Supabase issue, start with Vercel Environment Variables Not Working? 7 Supabase Fixes.

For the broader release process, see How to Use Vercel for Website Deployment: My 2026 Workflow.

Practical AI. Real Experience. Built in Public.

#Vercel#Environment Variables#Preview Deployment#Production#Next.js#Deployment
Share

Related reading

More practical notes are coming

The newsletter will open once the email system is ready. Until then, new articles are published directly on the blog.

Newsletter coming soon

Email signup will appear here once the mailing system is ready.