6

I want to use environment variables. I created .env.development file and I put some variables. Then I include the dotenv plugin to read the variables in gatsby-config.js:

require('dotenv').config({
    path: `.env.${process.env.NODE_ENV}`
});

The content of my .env.development:

GATSBY_APP=MYAPP

It's working in gatbsy-node.js but in browser (REACT) it's empty. I display console.log(process.env) and it return empty object.

Even if I install and configure gatsby-plugin-env-variables.

norbitrial
  • 14,716
  • 7
  • 32
  • 59
Youssef Lahssini
  • 121
  • 4
  • 11

4 Answers4

11

It looks like you're combining two approaches, and that might be where you're running into trouble.

  1. Gatsby comes out-of-the-box with support for defining environment variables in environment-specific .env.[environment] files (e.g. .env.development), provided these files are in the root of your project (i.e. your-project/.env.development). Documentation for this feature. You do not need to install or configure dotenv for this to work.

  2. Another approach is to use dotenv, which will allows you to use a general .env file. You need to then import and configure the tool, which is generally done at the very top line of gatsby-config.js and looks like this:

     require("dotenv").config()
    

Note that you do not specify the environment name (e.g. development) in this scenario, and you would not commit the .env file to your repository.

The other issue you might run into is that part of your code runs server-side, using Node, and part runs client-side (in the browser). Since process.env is only available in Node, Gatsby does some additional work to make it available in the browser. We don't want all of these variables, which frequently hold secrets, to be provided to the browser, though, so Gatsby only copies over those that whose names begin with GATSBY_. Finally, as a side effect of the way that these variables get copied over, you must explicitly reference them for your build to work:

// this is okay everywhere
const GATSBY_APP = process.env.GATSBY_APP

// this won't work in code that runs client-side, but will work
// in `gatsby-node.js` and other files that only run in Node
const { GATSBY_APP } = process.env
coreyward
  • 77,547
  • 20
  • 137
  • 166
  • I can't edit the answer because it's only a single character, but the env var prefix needs an underscore - it's GATSBY_ not just GATSBY – rubie Nov 29 '20 at 17:01
  • Coreyward, these aren't two different approaches to do the same thing, they do different things. According to the docs, Gatsby's default support enables putting env variables into the browser, while the dotenv method allows getting env variables into the node js files. He's right to do them both if he needs to access the variables in both places. I tested by just doing the default way and also tested passing in the env variable in the command line (both with GATSBY_ at the start of the variable name), but nothing gets to the browser. @Youssef Lahssini, did you ever figure this out? – Dale de Silva Sep 09 '21 at 00:56
  • @DaledeSilva I can assure you that either one works fine for getting `GATSBY_` prefixed env vars into the browser if you're configuring dotenv and not making the same mistake as the OP. I use this on dozens of websites. – coreyward Sep 09 '21 at 20:57
  • @Coreyward , you're right, both work for the browser :) I don't think there's any issue with both default and dotenv methods being present, though, since the way to get the env vars into the gatsby-*.js files (as opposed to browser) is to use dotenv even though the default method remains present - hence you have to have both if you need the env vars at build time. This issue the OP is having, though, is only related to his console.log. I had the same issue and submitted an answer describing it. – Dale de Silva Sep 11 '21 at 01:58
  • Note: I haven't actually tested this to see if some vars passed through the default method and some vars parse through the dotenv method all coexist when done together, but I have imported multiple env files with multiple dotenv calls and not had any issues - so I imagine it's fine. – Dale de Silva Sep 11 '21 at 02:00
1

If you wanted to whitelist your own environment variables, either as a prefix (shown here) or have a list of them, you can add something like this in the gatsby-node.js file:

exports.onCreateWebpackConfig = ({ actions, getConfig }) => {
    const config = getConfig();

    // Allow process.env.MY_WHITELIST_PREFIX_* environment variables
    const definePlugin = config.plugins.find(p => p.definitions);
    for (const [k, v] of Object.entries(process.env)) {
        if (k.startsWith("MY_WHITELIST_PREFIX_")) {
            definePlugin.definitions[`process.env.${k}`] = JSON.stringify(v);
        }
    }

    actions.replaceWebpackConfig(config);
};
odinho - Velmont
  • 20,922
  • 6
  • 41
  • 33
1

I was running into the same issue and just found out what I was doing wrong. It looks like you're doing the same thing.

The explanation both the documentation and @coreyward give are correct, however, note that while corey implies they're two different approaches and the issue might be that they're conflicting, they're not, they do different things - so that code of yours is fine.

What's wrong, though, is that you're console logging process.env. And as it turns out, this will always output an empty object even though the variables might be there.

You have to console.log(process.env.GATSBY_APP) directly to see any value. (Reference)

This is essentially an extension of what Corey pointed out in his "finally as a side-effect" section, however, the way he's written it implies it's an issue with destructuring - but it's not limited to that.

In my case, I was doing the above error AND not exposing the variables with GATSBY_ properly, then while testing I started logging the whole env object like you while I searched for the cause. This meant that even after I added the correct GATSBY_ prefix I still couldn't see anything.

So in short, it's probably only your console.log line that's an issue - access the variable directly, not the env object as a whole.

-2

The Gatsby site as a well documented section on working with environment variables. The gist is that the environment variables are only available during build time when the internal nodejs server is server rendering your site. In order, get those environment variables in the browser you need to programmatically embed them using the special gatsby-*.js files. The example they provide seems to be close to what you want to achieve.

nodox
  • 333
  • 1
  • 5
  • 16