It Worked on Localhost: The Environment Variable Checks I Make Before Blaming Production


 You build the app, test it on your laptop and everything works. Then you deploy it and something stops working. That can be frustrating, especially when you thought you were finished.

The page opens and the buttons are there, but login fails or an API request returns an error. Now you have to find out what changed between your laptop and the live site.

It is easy to blame the hosting platform first. Before I do that, I want to check the configuration. The live app may simply be missing a value that exists on my laptop.

An environment variable gives the application a value in a particular environment. Putting that value in a local .env file does not automatically create it on the production server.

It sounds simple, but this is the kind of detail you can miss when you are rushing to get the site online.

First, I check where I added the variable

Check the hosting settings for the deployment you are using. Production, preview and development can have separate values. Adding a key to preview doesn’t mean production received it.

These are the first three things I check:

  • the key exists in the hosting dashboard;

  • it is enabled for the environment I actually deployed;

  • the deployment happened after the value was added or changed.

Some values are included when the project builds. If I add one afterwards, refreshing the page won’t put it into the old build. I need to check whether the project requires a fresh deployment.

So the question is more specific than whether I added the key. Did the deployment I am opening actually receive it?

I compare the names carefully

In many systems, changing a capital letter changes the variable name.

SUPABASE_URL, Supabase_URL and SUPABASE_Url should be treated as different names. A missing underscore or an extra space can make the application read undefined even though the value appears to exist in the dashboard.

I put these three names beside each other and compare them:

  1. where the application reads it;

  2. where it is defined locally;

  3. where it is configured for production.

Copying the name helps me avoid a small typing mistake that creates another problem.

I check whether the value goes to the browser

Before changing anything, I need to know where this code runs.

Private credentials belong in server code, where visitors cannot read them. Frontend code is sent to the browser. If a value is included in that code, somebody using the site can usually inspect it.

A framework may use a prefix to expose a variable to the frontend. That prefix does not protect a secret. It tells you that the value can become public.

Some configuration is meant for the browser, such as a public project URL or a client key designed for public use with proper access policies. Private service keys and payment-provider secret keys must stay on the server. Check which kind of key you have before using it.

If a frontend request is failing, exposing a secret is not a fix I should use. I need to find the correct setup.

Then I check the value itself

A value showing in the dashboard doesn’t mean it is the right value.

Look for extra quotation marks or spaces. Check whether a multiline key kept its line breaks. Also confirm that you copied the production value rather than a value from another test project.

If I am unsure, I go back to the official service dashboard and check the source. Related values need to belong to the same project and environment too.

Mixing a URL from one project with a key from another can make the issue confusing. I want to rule that out before changing the application logic.

I check for the key without printing it

I may need to know whether the app received a key. I don’t need the whole key in the logs to answer that question.

For example, this checks whether a value exists without printing the secret:

console.log('API key configured:', Boolean(process.env.API_SECRET_KEY))

For a public URL, checking the hostname may help. With a secret key, keep the value out of logs. Those logs can be stored and other people may have access to them.

If a secret has already been exposed, deleting the visible text doesn’t undo that exposure. Replace or rotate the credential through the provider and update the app with the new value.

I find out when the app reads the value

The app may read a value during the build or while the server runs. I need to know which one applies.

A static frontend can include public configuration in its JavaScript at build time. Changing the hosting setting later won’t change that file. A serverless function may read configuration when it starts, so the steps needed to apply a change can be different. Check how your platform handles it.

Once I know when the app reads it, I can work out what needs rebuilding or restarting.

I look at the request that actually failed

A login button can look broken when the request is going to an undefined URL. A form can say “Something went wrong” when a server function is missing its key. The message on the screen is only the place to start investigating.

I start with the failed request in the browser Network panel, then check the server or function logs. I explained a similar way of following the problem in Authentication Bugs That Look Like Frontend Problems: find the stage where what I expected stopped happening.

The checks I want to finish before blaming production

Before changing more code, I ask:

  1. Does the exact variable name match the code?

  2. Is it configured for production rather than only preview or development?

  3. Was the application redeployed after the value changed?

  4. Does the value belong to the correct service project?

  5. Is the code running in the browser or on the server?

  6. Is any secret accidentally being exposed to frontend code?

  7. Is the variable read at build time or runtime?

  8. Does the failing network request contain the correct URL?

  9. Do server logs show that the configuration is missing?

  10. Does the same problem happen in a clean browser session?

When something works on my laptop, that gives me a useful starting point. I still need to compare the two environments and find what is different.

I want to treat configuration as part of building the app, not something I rush through at the end. As I explained in Building Digital Products for Nigerian Users, the work continues after deployment. I still need to check what happens for the person opening the site on their phone.

Post a Comment

Previous Post Next Post

Contact Form