How to access environment variables in a react component?

Hey there, I’m new to Gatsby and I’m creating a site with a google maps component that requires the google api key. I’m not able to access this key from the component (process.env.GOOGLE_API_KEY = undefined) however, even though I created an environment variable through the Netlify UI .

Am I missing something?

Thanks

2 Likes

This article is almost certainly the answer to your question:

If not, could you tell us more about how you are trying to use that value? That javascript looks fine, assuming that:

  1. you have that variable set during build
  2. that code RUNS during build (not, say, at browse time - where that is just a string, or anyway the environment variable isn’t set anymore) and interpolates its output into your static files.

Gatsby requirement

I also Answered this question on StackOverflow for the quick answer:

Environment variables need to start with GATSBY_ in the client-side javascript as shown in the docs.

Use GATSBY_GOOGLE_API_KEY and process.env.GATSBY_GOOGLE_API_KEY for them to be accessed during the build and bundled into your Gatsby client code.

4 Likes

Hi guys,

I have a similar situation but not really sure I understand best practice here. I have a config file that gets imported into the gatsby-node.js and gatsby-ssr.js files, to define some API credentials. One is a sensitive token and I cannot hardcode it, but when I add these to Netlify’s env vars settings and try to inject them with process.env, the variables are undefined error on build.

Contents of config file:

module.exports = {
  stores: [
    {
      subdomain: process.env.STORE_SUBDOMAIN,
      storefrontAccessToken: process.env.STORE_ACCESS_TOKEN,
      default: true,
    },
  ],
}

I see the suggestion to prefix them with GATSBY_, but doesn’t this expose them in the code?

What’s best practice for this flow?

Thanks!

How are you interpolating the values, Matthew? You do need to…you know…fill them in in your files from the settings, unless you use the $GATSBY_ prefix. We only process at build time, and only if you “do something to process them”. This article has more details, largely inspired by Talves :slight_smile:

Hey @fool, thanks for the reference. I read that article but I’m still a bit unclear on best practice and hoping for a specific example if you can help.

For a bit more context—I’m specifically trying to set a Shopify subdomain and access token (sensitive) by adding these values as environment variables in Netlify (prefixed for production vs staging, but that’s a different subject). These values are used with Shopify’s graphql API to retrieve product data.

I’m able to pull other Netlify-defined variables (CONTENTFUL_* vars) into my app inside the gatsby-config.js file, but trying to access the vars in this other file (config.js) doesn’t work. Is it possible that the config.js file just doesn’t get access to the process.env vars or am I setting these completely wrong?

So, how do I set a sensitive Netlify env variable and access it anywhere in my app?

the TL;DR is “explicitly interpolate the variables in THE ASSETS WE DEPLOY”. If we’re “running” the code at build time - e.g. node file.js - then process.env.XXXX will return a right value during that build - but the build process better write out the value, and not just “process.env.XXXX” to your published files - since node is NOT running at browse time :slight_smile:

To answer your specific final question:

  • You set it in netlify.toml or our UI (UI probably better if it is sensitive - keep it out of git)
  • you interpolate explicitly in your build process. There are a thousand ways you could do this. Naively, you could use something like sed:

sed s/PLACEHOLDER/${CONTENTFUL_SPACE_ID}/g filename.js

But, I guess you’re good at Node.js (I’m not) and could figure out a better process than a 45+ year old command line utility that I’m using :slight_smile:

@fool really appreciate your thoughts on this, but I think the part that’s throwing me off is that this works just fine locally with these variables in a .env.development file.

When running gatsby develop OR gatsby build and gatsby serve, it works in both scenarios. It just doesn’t work in Netlify.


I’m under the impression that the Netlify variables in deploy settings are a direct alternative to an env file and the variables should be sourced from there, so why would this work locally but fail during Netlify build?

not an answer, but a quick sanity check (this has come up before):

are you sure you are not blocking any of the required files from being added to your repo (and therefore to netlify) via a gitignore? :thinking:

Hey @perry.

Yep, definitely. The error I’m seeing in the build/deploy log is that the variables are undefined. I logged the stores variable and as you can see at the top of this screenshot, the variables in the array are undefined.

I’m under the impression that the Netlify variables in deploy settings are a direct alternative to an env file and the variables should be sourced from there, so why would this work locally but fail during Netlify build?

Not sure where you got that impression, but it’s not true. we don’t “do anything” with .env so if you don’t have your project set up to use it and also interpolate the variables from it, nothing will happen with them :slight_smile:

I thought I outlined that pretty clearly in the article I linked, but it didn’t seem that you received the message. Maybe reading it in a different way will help?

Hi,

I had a similar issue with Create React App, so leaving the solution for that here, in case it helps you to troubleshoot.

For Create React App, the solution ended up being that all Create React App environmental variables had to be prepended with REACT_APP_. So, process.env.REACT_APP_KEY would be defined, but process.env.KEY would be undefined.

(I had thought that the prepended part was only necessary for the local environment, but in fact it also was necessary in NODE_ENV=production).

Maybe Gatsby has some similar issue?

2 Likes

Hi Maiya! Thanks for sharing, I was having the same problem ( I was following a tutorial in which we made a conditional for the environment variable). Once I saw your post, I removed the conditional and kept it to the REACT_APP_… and it worked. Looking at the react docs they mention it as well. I don’t know why it was in the tutorial, maybe it is a bit outdated or something. Thanks!

1 Like

Hi @notayogilee, welcome to the community!

Can you tell me which tutorial it was that had the conditional? If it’s one that is from Netlify, I might be able to bring the issue to one of our teams to check. Thanks!!

Hi Dennis, thanks for the welcome. Sorry for the misunderstanding, it was not from a Netlify tutorial. It was from a Udemy course called React Front to Back by Brad Traversy (my favorite teacher). He is a big advocate for Netlify, and I understand why. In this tutorial, we were using the Github API to fetch the user, etc. when deploying to Netlify we used the conditional

if (process.env.NODE_ENV !== ‘production’) {
githubClientId = process.env.REACT_APP_GITHUB_CLIENT_ID;
githubClientSecret = process.env.REACT_APP_GITHUB_CLIENT_SECRET;
} else {
githubClientId = process.env.GITHUB_CLIENT_ID;
githubClientSecret = process.env.GITHUB_CLIENT_SECRET;
}

and set the env variables in Netlify. In this case, it worked. I don’t know why, but it did.
Then I tried it with a personal project and this is where I ran into a problem and found the solution here.
So all is good and keep up the great work. Cheers!

1 Like

That javascript is likely to work only during build, rather than at browse time - we don’t run server-side javascript during browse. But, during builds, don’t see any obvious reason that shouldn’t work well :slight_smile:

Just spent the better part of 1-2 hours trying to figure out why env vars were working in gatsby-config (locally and Netlify) but not in ContextProvider.js for shopify-buy, specifically:

    const client = Client.buildClient(
    	{
    		domain: `${process.env.SHOP_NAME}.myshopify.com`,
    		storefrontAccessToken: process.env.SHOPIFY_ACCESS_TOKEN,
    	},
    	fetch
    )

Prefixing env var keys with GATSBY_ fixed the issue! :+1:
I.e GATSBY_SHOP_NAME and GATSBY_SHOPIFY_ACCESS_TOKEN

Just wanted to confirm this for any other lost souls wondering in here, not knowing what to do :grinning:

2 Likes

thanks a bunch for sharing, @axelra82!