- Published on
Fixing 'Window is Not Defined' Error in Next.js
- Authors
- Name
- Ripal & Zalak
Fixing 'Window is Not Defined' Error in Next.js
When working with Next.js, a common error developers encounter is:
Unhandled Rejection (ReferenceError): window is not defined
This error occurs because Next.js executes code on the server side before rendering it on the client side. The window
object is specific to browsers and doesn't exist in the Node.js environment where the server-side rendering (SSR) occurs.
Why Does This Happen?
Next.js is a universal framework that renders JavaScript both on the server and the client. When code references window
during server-side rendering, it throws an error because the server has no concept of browser-specific objects like window
or document
.
Common Scenarios
- Accessing
window
in React lifecycle methods likecomponentWillMount
. - Using libraries that directly access
window
. - Inline scripts or dynamic rendering that rely on
window
.
How to Fix 'Window is Not Defined'
Here are the best solutions to resolve this issue:
window
Safely
1. Check for Wrap the code using typeof window
to ensure it's only executed on the client:
if (typeof window !== 'undefined') {
console.log('Client-side code execution')
}
useEffect
in Functional Components
2. Use In functional components, ensure browser-specific code runs only after the component mounts:
import React, { useEffect } from 'react'
const MyComponent = () => {
useEffect(() => {
console.log(window.innerWidth)
}, [])
return <div>Client-side component</div>
}
componentDidMount
in Class Components
3. Use In class components, move window
-dependent code to componentDidMount
:
class MyComponent extends React.Component {
componentDidMount() {
console.log(window.innerWidth)
}
render() {
return <div>Class component example</div>
}
}
4. Dynamic Import with No SSR
For components or libraries that depend on window
, use Next.js's dynamic import with ssr: false
:
import dynamic from 'next/dynamic'
const NoSSRComponent = dynamic(() => import('../components/SomeComponent'), { ssr: false })
const Page = () => (
<div>
<NoSSRComponent />
</div>
)
export default Page
5. Custom Hook for Client-Side Code
Create a custom hook for client-side rendering logic:
import { useState, useEffect } from 'react'
const useIsClient = () => {
const [isClient, setIsClient] = useState(false)
useEffect(() => {
setIsClient(true)
}, [])
return isClient
}
const MyComponent = () => {
const isClient = useIsClient()
if (!isClient) return null
return <div>Client-side rendering enabled</div>
}
window
Altogether
6. Avoid Using Whenever possible, use libraries or APIs that support server-side rendering without relying on browser-specific objects.
window
Errors
Best Practices to Avoid - Always Check for Environment: Use
typeof window !== 'undefined'
before accessing browser-specific objects. - Use Next.js Features: Leverage
dynamic()
andgetServerSideProps
where applicable. - Test Both Environments: Ensure your code runs smoothly on both server and client.
- Rely on Custom Hooks: Centralize browser-only logic in reusable hooks.
Frequently Asked Questions (FAQs)
localStorage
or document
in Next.js?
Q1: Can I use Yes, but ensure they're used only on the client side by checking typeof window !== 'undefined'
or using useEffect
.
dynamic
import fix the issue?
Q2: Why does Dynamic import with ssr: false
ensures the module is loaded only on the client, bypassing server-side execution.
window
in SSR?
Q3: What is the alternative to using Look for libraries that are SSR-friendly or rewrite your logic to avoid browser-dependent code during SSR.
Q4: Does this affect SEO?
Using dynamic
import or delaying rendering until client-side execution may affect SEO. Minimize such usage or ensure fallback content.
Conclusion
Resolving the "window is not defined" error in Next.js involves understanding the difference between server-side and client-side rendering. By following the solutions above, you can effectively handle this error and build robust, SSR-compatible applications.