I would like to set up a simple expression in my gatsby-config.js
that determines whether I am working locally or in production so that I can set the siteUrl<
You just need to set a .env.development
and .env.production
. Gatsby, by default, it will take the first one when you run a gatsby develop
command and the second in gatsby build
. Of course, you can change its behavior by changing your running script's command.
Once you set your .env.development
, it should look like:
SITE_URL: https://www.google.com
Then, this variable will be exposed in any Gatsby's file in the runtime. You only need to access it by:
module.exports = {
siteMetadata: {
title: "My title",
description: "My description...",
siteUrl: process.env.SITE_URL
}, {
...
}
You can check the active environment by checking GATSBY_ACTIVE_ENV
variable like:
siteUrl: process.env.GATSBY_ACTIVE_ENV==='development' ? '/' : 'https://example.com'
You can change the default behavior by changing the running script in your package.json. For example:
"develop": "GATSBY_ACTIVE_ENV=whatever gatsby develop",
Now, GATSBY_ACTIVE_ENV
would be whatever
in a develop
mode.
For further reading, check Gatsby's docs
Yes you can, by setting up environment variables.
Create some .env.*
files in root folder for different environments.
Docs here: https://www.gatsbyjs.org/docs/environment-variables/
After some trial and error, I've found the solution to my problem (along with a couple of gotchas).
The first distinction I had to make was between OS vars and project vars, as per the Gatsby docs. I wasn't too clear on that but decided that my root URL was a project environment variable as it changed depending on whether I was in production or development.
That said, I only needed to define my URLs in their respective .env
files:
// .env.development
SITE_URL=http://localhost:8000
N.B: You have to define the HTTP protocol on localhost, otherwise you'll run into an unhandled rejection, invalid URL
error with Gatsby link
. I found it has to be HTTP to work.
// .env.production
SITE_URL=https://myproductionsite.com
Next, in my gatsby-config.js
, I had to include the dotenv
package at the top (as also noted in the Gatsby docs):
// gatsby-config.js
require("dotenv").config({
path: `.env.${process.env.NODE_ENV}`,
})
However, trying to spin up the gatsby development (or production) server, I kept running into a problem with can't resolve 'fs' module
. I came to find this article from Gatsby troubleshooting docs and added the following to my gatsby-node.js
file to resolve it:
exports.onCreateWebpackConfig = ({ actions }) => {
actions.setWebpackConfig({
node: {
fs: "empty",
},
})
}
So ultimately, I was able to simply put the following in my siteMetadata
section of the gatsby-config.js
file:
// gatsby-config.js
require("dotenv").config({
path: `.env.${process.env.NODE_ENV}`,
})
siteMetadata: {
title: "My Site",
description: "My description...",
...
siteUrl: process.env.SITE_URL,
...
This produces the desired behavior, calling up the proper SITE_URL variable based on environments.
Also note, this issue only happened when I included the property siteUrl
in my siteMetadata
object. If I could have taken it out I would have but am using it as a sitewide variable for SEO purposes and more.
Gotcha: If you're using Netlify you'll need to set up an Env Var in your build environment matching SITE_URL
or else your build will break as the production variable won't work in the gatsby-config
as is.