referenceerror: window is not defined, how to solve
By Flavio Copes
Learn how to fix the referenceerror: window is not defined error in Node.js or Next.js by guarding browser-only code with a typeof window check first.
Here’s how to fix the “referenceerror: window is not defined” error that you might have in Node.js or with a tool like Next.js: find the code that uses window, and make sure it only runs in the browser.
Why does this error happen?
window is an object that’s made available by the browser, and it’s not available in a server-side JavaScript environment.
I describe the window object in detail in my extensive DOM Document Object Model guide.
You are running frontend code in a backend environment.
The usual triggers: accessing window, document or localStorage at the top level of a file, or importing a library that does so as soon as it loads.
With Node.js in particular there’s no way to work around the problem. You must find the particular place where window is used, and revisit the code to figure out why you are accessing the window object.
How to fix it in Next.js
In Next.js this error is common because the same code runs in two places.
In Next.js 16, new projects use the App Router. Pages and layouts are Server Components by default. A Server Component only runs on the server, so window and localStorage never exist inside it.
Move the code that needs them into a Client Component, by adding 'use client' at the top of its file.
Client Components are where the “two places” part comes in. Next.js prerenders them to HTML on the server, then runs them in the browser. So inside a Client Component, window and localStorage must sit in a useEffect() hook or behind the check below.
If your app uses the older Pages Router, the code runs in the browser when you navigate to a page using a link, and server-side when Next.js renders the page, for example when you use getServerSideProps().
In both cases, you can limit the reference into a conditional that checks if the window object is available, like this:
if (typeof window !== 'undefined') {
//here `window` is available
}
And this will fix your problem, since you only run anything inside the conditional in a browser environment.
Don’t use this check to decide what a component renders. The server and the browser would produce different HTML, and you’d get a hydration error.
Alternatively, you can move the browser-only code inside a useEffect() hook:
useEffect(() => {
console.log(window.innerWidth)
}, [])
Effects only run in the browser, after the component is mounted, so window is guaranteed to exist inside them. In the App Router, this code goes in a file that starts with 'use client', because Server Components can’t use useEffect().
Be careful how you write the check
You need the typeof part. This version does not work:
if (window !== undefined) {
//...
}
That line throws the exact same “window is not defined” error, because reading a variable that was never declared is itself a ReferenceError.
typeof is the one operator that’s safe to use on names that don’t exist. Instead of throwing, it returns the string 'undefined'. That’s why the fix always starts with typeof window.
Want me to talk about your product? You can sponsor this site.
Related posts about node: