While working on the Next Js project, you may have faced an issue saying ‘window is not defined’. Next js provides a powerful framework, that helps to create server-side rendered applications and that is by using Javascript.
But most of us face this ‘window’ or ‘document’ as an undefined issue because these are client-side available variables which are not available to be used on the client-facing end.
[lwptoc]
In this article, we will dive deep into the root cause of the ‘window is not defined’ or ‘window is undefined’ error, try to discuss use-cases when this issue appears, its course and of course various ways to resolve it.
The ‘window’ Object in JavaScript
In Javascript, a window
is a global object which represents the browser’s window. The window object keeps the global objects related to functions and variables. For example when we declare a variable a
, then we are able to access it using the window.a
or by just using a
:
let a = 10;
console.log(window.a); // Outputs: 10
console.log(a); // Outputs: 10
Why do we face the ‘window is not defined’ issue in Next.js
React-powered framework, Next JS supports the Server-Side rendering (SSR) of pages. In SSR, the Javascript code is executed on the server-side first and then sent to the client end.
The window object, which is a browser-specific global object, can’t be accessed on the server side. So when we try to give reference to the window
object in our Next js app while server-side rendering, we face the ‘window is not defined’ error.
console.log(window.location.href); // Throws 'window is not defined' error in Next.js during SSR
When the ‘window is not defined’ Error is Encountered?
In this session, we will focus on various use cases, when developers may face the window not defined issue. We will discuss these scenarios with the help of sample code examples:
1. Using window
in getServerSideProps
Hook:
The getServerSideProps
function in Next.js is used for server-side rendering which is executed on the server side and not the client side. So whenever we try to reference the window
object inside getServerSideProps
, we will face the window is not defined error.
export async function getServerSideProps(context) {
console.log(window.location.href); // This will throw 'window is not defined' error
return {
props: {}, // will be passed to the page component as props
};
}
2. Using window
in a Next.js API Route:
Next js API routes help in building the APIs using the server-side code. If we try to use the window object in an API route for any reason, we will face the window undefined error.
// pages/api/hello.js
export default function handler(req, res) {
console.log(window.location.href); // This will throw 'window is not defined' error
res.status(200).json({ name: 'John Doe' });
}
Solutions for ‘window is not defined’ Error in Next.js
We have discussed in detail about what this issue and why we face it, now let’s discuss the following possible solutions in detail:
Sol. 1 – Using 'typeof'
to Check the Existence of a ‘window’
Sol. 2 – Utilizing the useEffect
React Hook
Sol. 3 – Dynamic Loading with SSR (Server-Side Rendering) Set to False
Sol. 1 – Using ‘typeof’ to Check the Existence of ‘window’
One of the quick-fix solutions is to use the typeof
operator to check the availability of window
. The typeof
operator returns a string to disclose the type of the unevaluated operand. Here is how we can use it:
// pages/index.js
export default function Home() {
if (typeof window !== "undefined") {
console.log(window.location.href);
}
return (
<div>
<h1>Welcome to Next.js!</h1>
</div>
);
}
Above, we are checking the value returned by window using the typeof, if window exists it will return an “object” else it will be “undefined”.
Sol. 2 – Utilizing the useEffect React Hook
We can also use the useEffect hook which performs the side effects in a functional component. It is used to execute code after the first render and thereafter every update.
It runs on the client side where window
object available to be accessed. Let’s have a look at how we can leverage useEffect to avoid the window undefined issue:
// pages/index.js
import React, { useEffect } from "react";
export default function Home() {
useEffect(() => {
console.log(window.location.href);
}, []);
return (
<div>
<h1>Welcome to Next.js!</h1>
</div>
);
}
Sol. 3 – Dynamic Loading with SSR (Server-Side Rendering) Set to False
Next js also allows the dynamic import of modules, which are loaded at the runtime instead of module loading time. We can disable the server-side render for a specific module by setting the ssr options to false to do so. Let see how to do it:
// components/ShowWindowLocation.js
import React from "react";
export default function ShowWindowLocation() {
console.log(window.location.href);
return null;
}
// pages/index.js
import dynamic from "next/dynamic";
const ShowWindowLocation = dynamic(() => import("../components/ShowWindowLocation"), { ssr: false });
export default function Home() {
return (
<div>
<h1>Welcome to Next.js!</h1>
<ShowWindowLocation />
</div>
);
}
Above, we are dynamically importing the ShowWindowLocation
component with ssr
set to false
. This means the ShowWindowLocation
component will be loaded on the client side where the window
object is available.
Conclusion
In this detailed guide, we discussed why we face window is not defined issue its possible reasons and three quick solutions with examples including:
- Using
typeof
to check the existence ofwindow
- Utilizing the
useEffect
React hook - Dynamic loading with SSR (Server-Side Rendering) set to false
Hope this detailed guide will be helpful and you will be able to resolve the window is not defined issue in best possible way.