Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I fix the 'window is not defined' error while using react-leaflet and Next.js?

I am using Leaflet to generate a Map for my website, but it seems to be causing a window is not defined error.

I have been searching for a while and the cause of this issue appears to be that leaflet is attempting to load the map prematurely, as in before a window even exists, hence the error.

Alright so,

I have tried dynamically importing the Map from its source using next/dynamic

Example code:

  const Map = useMemo(
    () => dynamic(() => import("@/app/components/Map"), { ssr: false }),
    // eslint-disable-next-line react-hooks/exhaustive-deps
    [location]
  );

I also tried using a ../components/Map import instead of @/app/components/Map

Another thing that was mentioned is to use the dynamic import OUTISDE the main function, which would end up looking like this

 const Map = dynamic(() => import("@/app/components/Map"), { ssr: false });

Not only did this not fix my issue, it removes the reason I am using useMemo, which is to make sure that everytime the location changes the map is updated to go to that location.

Another thing that I tried was using an isMounted state where I'd make a useState, set it to false, and make it to true using useEffect

Example:

const [isMounted, setIsMounted] = React.useState(false)

useEffect(() => {
 setIsMounted(true)
}, [])

I'd have this in the Map component and have it only render if isMounted is equal to true as I had a return function to null before it

Example:

if(!isMounted) return null;

return (
 <Map></Map>
)

I have also tried messing around with the { ssr: false } option, removing it, making it true, but nothing worked. I keep consistently getting this error, so I'd love some help!

like image 471
Ahmad Nasser Avatar asked May 29 '26 19:05

Ahmad Nasser


1 Answers

You need to move the dynamic import outside of your react component or page, as it is the correct way to use next/dynamic. Lets say you had a prop that was called location that changes whenever you need your component to re-render, then you could do something like this:

const Map = dynamic(() => import("@/app/components/Map"), { 
  ssr: false,
});

interface Props {
  location: string;
}

export default function OtherComponent({ location }: Props): JSX.Element {
  // Since you want your component to re-render each time the location prop
  // changes, we pass the `key` prop to the component. This will force the
  // component to re-render.
  return <Map key={location} />;
}

export type { Props as OtherComponentProps };

As a side note, you are encountering the window is not defined error because the 3rd-party component tries to access Window API's that are not available on the server.

like image 57
Fabio Nettis Avatar answered May 31 '26 09:05

Fabio Nettis



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!