Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Window is not defined with custom react hook

I am facing a problem I can't seem to solve.

I have a custom hook that sets the height and width of the window. But since nextjs is SSR I get the error that window is not defined.

My problem lies in putting the hook in a if statement or useeffect hook.

Current code (useWindowDimensions.tsx):

import { useState, useEffect } from 'react'

function getWindowDimensions() {
    const { innerWidth: width, innerHeight: height } = window
    return {
        width,
        height,
    }
}

export default function useWindowDimensions() {
    const [windowDimensions, setWindowDimensions] = useState(getWindowDimensions())

    useEffect(() => {
        function handleResize() {
            setWindowDimensions(getWindowDimensions())
        }

        window.addEventListener('resize', handleResize)
        // code here
        return () => window.removeEventListener('resize', handleResize)
    }, [])

    return windowDimensions
}

Current code:

const { height, width } = useWindowDimensions()

const dimensions = () => {
        if (width > 1900) return width * 0.4
        if (width > 1000) return width * 0.3
        if (width > 800) return width * 0.2
        if (width < 800) return width * 0.1
    }

I can't put getWindowDimensions() in an useEffect because the rules of hooks

useEffect(() => {
    function getWindowDimensions() {
        const { innerWidth: width, innerHeight: height } = window
        return {
            width,
            height,
        }
    }
})
like image 500
elmgren Avatar asked Jul 22 '26 00:07

elmgren


2 Answers

You are getting the error because in Next.js your code is first server side rendered, and on server there are no browser globals like window, document, etc. To fix it, you can do this:

export default function useWindowDimensions() {
    const [windowDimensions, setWindowDimensions] = useState({width: 0, height: 0}) // <-- don't invoke here

    useEffect(() => {
        function handleResize() {
            setWindowDimensions(getWindowDimensions())
        }

        handleResize() // <-- invoke this on component mount
        window.addEventListener('resize', handleResize)
        
        return () => { window.removeEventListener('resize', handleResize) }
    }, [])

    return windowDimensions
}

It will work because useEffect is guaranteed to run on client side only.

Also refer: Window is not defined in Next.js React app and How to detect window size in Next.js SSR using react hook? if you wish to create a hook that handles this for you.

like image 119
brc-dd Avatar answered Jul 24 '26 17:07

brc-dd


Check if window is defined or not:

if (typeof window !== 'undefined') {
  // You now have access to `window`
}

https://nextjs.org/docs/migrating/from-create-react-app#safely-accessing-web-apis

like image 31
Shahriar Avatar answered Jul 24 '26 16:07

Shahriar



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!