Problems with environment variables

Hi there,

I am running a Gatsby site, now that I have branch deploys working and being deployed to the right subdomain, I would like to set an ENVIRONMENT VAR for my STAGING Branch Deploy.

I have been reading all the threads I have found , but had not success yet.
Development and Production were working fine using .env.XXX files. until now, but that’s Gatsby normal build process.

I have been trying to create a .end.STAGING file without sucess, now I am moving the variables to netlify.toml but still struggling to get it working.

In my netlify.toml I have added:

NODE_ENV = “staging”

Overall idea is, the WEB_URL is going to be different when in production. (This is the first simple step to change ENDPOINTS)

Well, none of the variables is accessed during build:

  • NODE_ENV is not updated and .env.staging is not read (now this has been removed from repo)
  • WEB_URL is undefined when accessed to do: <a href={process.env.WEB_URL + “/projects”}>

Any idea on what to test?


From the Gatsby documentation for environment variables:

To expose a variable in the browser, you must preface its name with GATSBY_

Do you think that could be the issue?

You could also write a test page with a script to console.log your process.env and see what is being processes on your build.

HI @talves,

thanks for answering, I do not think this is the answer. AFAIK GATSBY_ variables are used to exposed them to the client.
I only need them to used them at Build time (so, Server side, so to say).

I have been able to explore more, now my build command in netlify.toml is:

command = “yarn env && gatsby build”

And in the log file I can see variables are being set:

“WEB_URL”: “”,
“BUILD_ENV”: “staging”,
“NODE_ENV”: “staging”,

But from the react code they appear as “undefined”.

As I know “gatsby build” command overwrites “NODE_ENV” to “production” I am using “BUILD_ENV” as an alternative and in my gatsby-config.js I have:

const build_env = process.env.NODE_ENV == ‘development’ ? ‘development’: process.env.BUILD_ENV


path: .env.${build_env}


trying to force a diferent .env.xxxx file.

But no success.

My staging environment is pointing to production Endpoints and is driving me crazy.


So, have you confirmed the process.env.NODE_ENV gets changed to staging? Interesting.

I know netlify defaults the NODE_ENV to development, so dev deps get loaded.

1 Like

Hi @mustainer ,

I did a test repo to make sure, since it’s been awhile since I’ve done this. I created a staging branch and changed the Netlify app to deploy the branch staging.

I did see the process.env.BUILD_ENV from the node env correctly from context.staging.

Also process.env.CONTEXT shows as branch-deploy, so you could also check off of that in your build code to check for a non production branch deploy. process.env.CONTEXT for the production build did have production, so the statement in my last reply does not apply as far as I can see.

Here is the repo I used for testing if you want to run it in a repo or use the code: GitHub - talves/netlify-env-vars: Testing a deploy from branches checking the context

NOTE: If you don’t set process.env.NODE_ENV then it will be undefined. Make sure if you do this is what you want to affect your build process.


Thanks @talves for the time dedicated to this issues, really appreciated.

I have this in my .toml:

BUILD_ENV = “staging”

When I deploy in the Build Logs this traces appear:

10:04:15 AM: “WEB_URL”: “”,
10:04:15 AM: “BUILD_ENV”: “staging”,

Up to now everything looks fine.

But when in my Gatsby React component I do:

console.log(“BUILD_ENV=” + process.env.BUILD_ENV)
console.log(“WEB_URL=” + process.env.WEB_URL)

Also in the build log, because Gatsby processes the components in build time it says:

10:04:50 AM: BUILD_ENV=undefined
10:04:50 AM: WEB_URL=

That are the Production variables :frowning:

a bit lost now.

I assume this is because Gatsby is forcing NODE_ENV to be Production when “gatsby build” is run, and then reading from the .env.production file no matter what.

But this makes testing more complex in netlify.

Hey there, @mustainer :wave:

It looks like you’re experiencing something similar to what we debugged in this thread below. Can you please take a look and follow the proposed steps?

Additionally, I want to dive into this point and hopefully clarify some differences between server-side variable and build time variables:

Server-side variables are variables accessible to functions and defined in the UI. Build time variables are defined in your TOML and are not accessible to functions. Knowing this, could you save your variables in the Netlify UI rather than using .env files?

Let me know if this gets you on the right path!

1 Like

Hi @hillary

thanks for the answer, let me answer your two suggestions.

About the first thread, yes I already read it before posting. According to Gatsby documentation variables GATSBY_xxx are used to be accessed by the browser as exposed here:

This is not what I want, my vars are only needed in build time to change the endpoints being accessed.

To your second point. Just to clarify, I do not need these variables to be accessed by any functions, just Gatsby Build process. I have tested both approaches having .env files and setting them up in the toml file.

No success.

As I want the variables to have different values for production and staging (branch deployment) using the UI is not a valid option, my reasoning:

  • UI does not allow me to have different values per different deployment type, they are all shared.
  • Then, I would need to use different VAR names, like. PROD_VAR, STAGING_VAR
  • Having different VAR names is forcing me to detect in build time in what type of deployment the build is being run to use one or the other
  • and then I am back to my original problem…

Gatsby is not reading the variables setup neither in .env.staging, neither in TOML file.

I am sure this is some mis-configuration on my side, or not clearly understanding something in Gatsby, but I am blocked with this right now.

I will make some more tests today and try to bring logs and examples with TOML file defined variables.


I think it was clue on how you could possibly try to access the variables. If setting it in .env file is not working, you could set it in the build command like how Hillary has suggested. You could choose to exclude the GATSBY_ prefix.

Hi @hrishikesh,

thanks for the answer, the truth is that I am completely lost now, so I am going to post my current status just in case someone finds this helpful but I am going to focus on some other priorities now.

I have tested what you said:

  1. My current netlify.toml file:

publish = “public”

BUILD_ENV = “production”

BUILD_ENV = “staging”

  1. My config file has the following:

const build_env = process.env.NODE_ENV == ‘development’ ? ‘development’: process.env.BUILD_ENV

console.log("BUILD_ENV = " + process.env.BUILD_ENV)
console.log("Calculated = " + build_env)

  1. One of my react components has:

console.log(“BUILD_ENV=” + process.env.BUILD_ENV)
console.log(“WEB_URL=” + process.env.WEB_UR

In summary, variables are defined in TOML file, injected through the build command and I am using them in two different files to test how gatsby accesses them.

Parts of my Build Log file:

7:43:38 PM: Found a Gatsby cache. We’re about to go FAST. :zap:
7:43:38 PM: BUILD_ENV = staging
7:43:38 PM: Calculated = staging
7:45:05 PM: success Writing page-data.json files to public directory - 0.004s - 10/10 2241.06/s
7:45:10 PM: CSS_CLASS=undefined
7:45:10 PM: WEB_URL=undefined
7:45:10 PM: CSS_CLASS=undefined
7:45:10 PM: WEB_URL=undefined
7:45:10 PM: CSS_CLASS=undefined
7:45:10 PM: WEB_URL=undefined
7:45:10 PM: success Building static HTML for pages - 4.695s - 10/10 2.13/s
7:45:11 PM: success onPostBuild - 0.066s

Seems that the TOML variables are accesible at some point while building but not when the real react build is going on.

I have tested that also with .env files and the result is a bit better, only .env.production variables are read.
At least the app ends with some version of the variables.
Without .env files, gatsby is not reading even the production declared vars.

Very rare.

I do not expect an answer just leaving this here for future members

Thanks for all the support.