Gatsby - the window is not defined error, what and how to fix it?

Co-Founder, @CreoWis | Teacher, @tapaScript | Founder, @ReactPlay | YouTuber | Writer | Human
Search for a command to run...

Co-Founder, @CreoWis | Teacher, @tapaScript | Founder, @ReactPlay | YouTuber | Writer | Human
Traditional SSR is great, but it has a massive buffering problem. Let's look into the SSR Streaming and learn how it could be a game changer.

Learn how to build maintainable, reusable forms in React using design patterns like custom hooks, compound components, and context for scalable CRUD

Learn how JavaScript variables work, including let vs const, primitive and reference types, pass by value, and how JavaScript stores data in memory.

A beginner-friendly introduction to JavaScript covering what it is, how it works, and how to set up your JavaScript environment

Learn how the promises are handled internally using event loop. This concept is essentials to debug and work with async programming.

GreenRoots Blog - A Blog by Tapas Adhikary
186 posts
Educator | YouTuber | Building ReactPlay | Let's Connect
Gatsby is one of the most popular Static Site Generators available to create pre-built markups for Jamstack apps. It is a React-based framework that offers a plethora of plug-in ecosystems to make life comfortable for the developer community. I have been using Gatsby for a couple of years now, and my experience is very good with it except for a few glitches.
We will talk about one such glitch that I have faced and luckily found reasonable solutions for it. I hope you find it useful.
You can run a Gatsby-based application in two different environments,
gatsby develop: A development environment enabled with hot-reloading. In this environment, all browser-specific APIs like localstorage, or the globals like window, document, etc., will work well.gatsby build: It is the environment to build the application to produce deployable artifacts. You can even run the app locally from the deployable artifacts using the gatsby serve command. Unlike the development environment, the build environment is based on nodejs.
The nodejs environment doesn't have the browser-globals like window, document, etc. Hence if the source code has a reference to them, you are more likely to get a build failure with the error, window is not defined.

Please note: You may also face this error when you use a client-side library(maybe, an npm) that contains a reference to
window,document, etc.
There are multiple ways to fix/ignore this error. You may want to use the one most suitable for you.
window is definedYou can check if the browser-global object window is defined and based on it, execute the related code block.
const isBrowser = typeof window !== "undefined"
The variable isBrowser helps you to determine if the window object is available in the environment. Let's use it to check and call a method to get an item from the browser's local storage.
export const isAuthenticated = () => {
if (!isBrowser) {
return;
}
return window.localstorage.getItem("isLoggedIn") === "true"
}
You can also consider writing it as a simple util function like,
// utils.js
export const isBrowser = () => typeof window !== "undefined"
and then use it elsewhere,
import { isBrowser } from './utils';
if (!isBrowser) {
return;
}
// ... other code
useEffect hook or componentDidMount methodGatsby is a React-based framework. If the problematic code is in the component's render function, move that code into a useEffect hook or a componentDidMount lifecycle method. It will ensure the code doesn’t run unless it’s in the browser.
You can also fix/ignore this error at the configuration level. This solution is more apt for the third-party modules/libraries/npms depending on the window object. You can customize your webpack configuration to replace these modules with a dummy module during server rendering.
To do that, open the gatsby-node.js file and add this at the end of the file,
exports.onCreateWebpackConfig = ({ stage, loaders, actions }) => {
if (stage === "build-html") {
actions.setWebpackConfig({
module: {
rules: [
{
test: /offending-module/,
use: loaders.null(),
},
],
},
})
}
}
The word offending-module has to be replaced with the actual module name. For example, if you are using auth0 with Gatsby, you can mention the module name as auth0-js in the above configuration. Using Webpack’s null loader, we will effectively ignore auth0-js during the build.