For a recent project we were struggling to get the '.env' variables into our public documents. As for security we should keep sensitive information away from daylight. That’s why it’s important to work with these environmental variables. Some might have found the same difficulties, but when working with frameworks I experienced there are some extra conditions you have to pay attention to.
For our project I started out with a MERN project, my teammate started to research Gatsby and Cloudinary and started out there. Since Gatsby is based on React we figured there wouldn’t be compatibility issues. Yet we found out by experience of combining our work into one project folder, each framework works with a different set of rules regarding the use of '.env' variables. For implementing my files in the Gatsby project I had to research the differences. This article highlights the differences in implementation of these variables in the Gatsby and React frameworks.
Implementing environmental variables in you project
For starters: this is a universal instruction. Go to the root of your project in your terminal (where the 'package.json' file is stashed). Normally there should be a 'package.json' already, else you need to make one first.
To use this dependency you need to install the dotenv package. I mainly work with npm package manager but you can also install this package with yarn:
npm i dotenv
or
yarn add dotenv
Now the dotenv module is added to your dependencies in the 'package.json' file.
React
To define your environmental variables you basically just need a '.env' file, but if you're working with different environments you can add specifications to the filename (see official docs of React; link in title).
touch .env
There you can start adding your sensitive information in variables. It is necessary you start with REACT_APP_ before the variable name, otherwise the variables won't be read.
//.env
REACT_APP_ATLAS_DB_NAME=string
To use '.env' in your React project you have to paste this code at the top of each file where you want to use an environmental variable:
// index.js
/* CommonJS */
require('dotenv').config();
/* ES6 Modules */
import dotenv from 'dotenv';
dotenv.config({path: '/server/.env'});
// package.json
/* CommonJS */
...
"type": "commonjs",
...
/* ES6 Modules */
...
"type": "module",
...
Gatsby
In Gatsby you cannot work with a plain '.env' file but only with '.env.development' or '.env.production'.
Depending on the cli command the needed '.env' file will be processed when hosting:
- Development
If you run 'gatsby develop', then you will be in the development environment.
- Production
If you run 'gatsby build' or 'gatsby serve', then you will be in the production environment.
You can put your environmental variables in either a '.env.development' or '.env.production' file, it's recommended to start with the development and change this file to a production type:
touch .env.development
or
touch .env.production
In this case it is necessary you start with GATSBY_ before the variable name, as it is the same for when using only React: the variables won't be read otherwise.
//.env.development
GATSBY_ATLAS_DB_NAME=string
To use '.env' in your gatsby project you have to paste this code at the top of your gatsby-config.js file:
// gatsby-config.js
require("dotenv").config({
path: `.env.${process.env.NODE_ENV}`,
});
So Gatsby doesn’t per se work with the strict ES6 module type (but it is possible with the esm plugin). The gatsby-config.js doesn't allow import syntax, only the require.
There's no need to add - "type": "module" - to the 'package.json' file.
Using the variables in your public files
Now you can retrieve this value in your server and client side (pages, components) by starting with 'process.env.' and adding the variable name:
// Example gatsby-config.js
resolve: 'gatsby-source-mongodb',
options: {
// Name of the database and collection where are books reside
dbName: process.env.GATSBY_ATLAS_DB_NAME,
...
}
// Example src/pages/index.js (Gatsby) src/index.js (React)
render() {
return (
<div>
<img src={`${process.env.GATSBY_API_URL}/logo.png`} alt="Logo" />
OR
<img src={`${process.env.REACT_APP_API_URL}/logo.png`} alt="Logo" />
</div>
)
}
When working in React chances are you're working with a server and client folder. I didn't manage to use the '.env' file from server to client by path. An experienced developer I know said he uses a file per folder. I'm still hoping to get this done by using the path option in the config function (config({path: '/path/.env})), but the documentation I have found so far hasn't provided me with the solution.
If you know advice on this you can always help me by commenting on this article!
And never forget: when you deploy your files on GitHub, make sure your '.env' files are listed in the '.gitignore' file you put at the root of the project and you'll serve the purpose of this set-up.
Top comments (1)
Good write up! Helped me out with sorting our env variables in a Gatsby project. one thing though is that I did not prefix each env variable with GATSBY_. From my understanding prefix is only required if you need these values at build time.