1

I wrote this code in next.js but I encountered an error. The error says "NextJS - ReferenceError: window is not defined". can you help me how can i fix it

function IconWeatherComponent({icon}) {
    
    let [svg, setSvg] = useState('');
    
    
    useEffect(() => {
        const setIcon = () => {
            if (icon === '01d') {
                setSvg('day.svg')
            }
            if (icon === '01n') {
                setSvg('night.svg')
            }
        setIcon();
    }, [icon])
    
    
    return (
        <div>
            <img src={`${window.location.origin}/weather-icons/${svg}`} width="70" height="70" alt=""/>
        </div>
    );
}

export default IconWeatherComponent
2
  • 1
    Does this answer your question? Window is not defined in Next.js React app Commented Dec 6, 2022 at 20:28
  • Thinking on this further, do you really need to be accessing the window location? If these svg file are in the same project, you can import them directly into this component. That would be better unless for some reason you can't include those files in this repo. Commented Dec 6, 2022 at 20:51

3 Answers 3

1

window is not defined at build time, so it can't be accessed directly in your JSX. It is only defined in the browser. You will need to check for the location only at runtime, in a useEffect hook.

function IconWeatherComponent({icon}) {
    
    let [svg, setSvg] = useState('');
    const [location, setLocation] = useState('');
    
    useEffect(() => {
        const setIcon = () => {
            if (icon === '01d') {
                setSvg('day.svg')
            }
            if (icon === '01n') {
                setSvg('night.svg')
            }
        setIcon();
    }, [icon])
    
    useEffect(() => {
        if (typeof window !== 'undefined') {
            setLocation(window.location.origin)
        }
    }, []
    
    return (
        <div>
            <img src={`${location}/weather-icons/${svg}`} width="70" height="70" alt=""/>
        </div>
    );
}

export default IconWeatherComponent
Sign up to request clarification or add additional context in comments.

Comments

0

You want to access window object but in this solution window is not define. Add your code to a usseefect and save data to state.hope solve your problem

Usseefect (()=>{Setwindowlocation(window.location.origin)},[])

Comments

0

I find the accepted answer correct but slightly overkill, because it involves handling state in your component, and the image URL will be inconsistent while the component is mounting.

It is ok to use the window object directly in your render function, in this situation, I would rather rely on a useMounted utility:

const useMounted = () => {
    const [mounted, setMounted] = useState<boolean>()
    // effects run only client-side
    // so we can detect when the component is hydrated/mounted
    // @see https://react.dev/reference/react/useEffect
    useEffect(() => {
        setMounted(true)
    }, [])
    return mounted
}

// in your component
const mounted = useMounted()
// render nothing server-side and during first render, or a placeholder
if (!mounted) return null
return (
        <div>
            <img src={`${window.location.origin}/weather-icons/${svg}`} width="70" height="70" alt=""/>
        </div>
    );

Also, you don't need an effect + state to compute a value derived from props, see the new "You might not need an effect" section in React documentation.

More broadly, this "window not defined" error comes up in different shapes in Next.js, all vaguely related yet not exactly the same.

I've summarized all the possible situations in an answer to a similar question.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.