Next js with react-leaflet window is not defined when refreshing page
Asked Answered
H

6

14

im using react-leaflet in Next js but when reloading page shows "window is not defined" even i am using dynamic import with ssr:false, i saw this question made by others here and tried answers that they offered but didn't work, also tried to make the map mounted after component but again no result, my code:

function ContactPage() {
    const MapWithNoSSR = dynamic(() => import('../Map/Map'), {
        ssr: false,
    })
    return (
        <div className={styles.map}>
            <MapWithNoSSR/>
        </div>
    )
}

function Map(){

const [markers, setMarkers]= useState([
        {cord:[12.3774729,20.446257]},
        {cord:[45.3774729,10.45224757]},
        {cord:[40.3774729,15.4364757]},
    ])

<MapContainer center={[12.374729,22.4464757]} zoom={13} scrollWheelZoom={true} style={{height: "100%", width: "100%",zIndex:'1'}}>
          <TileLayer
              url={`example.com`}
              attribution='Map data &copy; <a>Mapbox</a>'
          />
          {markers?.map((element,idx)=>{
            return <Marker
                position={element?.cord}
                draggable={true}
                animate={true}
                key={idx}
            >
              <Popup>
                Test PopUP
              </Popup>
            </Marker>
          })}
        </MapContainer> 

}}
}
Hypertrophy answered 29/6, 2021 at 11:49 Comment(3)
The dynamic() call can't be used inside of React rendering, it needs to be declared at the top level of the module for preloading to work. Have a read through Dynamic Import for details.Columbarium
Julio i put outside of component but still getting error window is not defined, should i put the dynamic import in folder "pages" then to my page or can i put in the component ?Hypertrophy
I've provided a detailed answer in another question, dealing with this precise use case (package that crashes when being imported server-side, like Leaflet or jQuery) but also some other (the page can be imported but can't be rendered server-side (like d3): https://mcmap.net/q/99931/-window-is-not-defined-in-next-js-react-appArgumentum
S
21

as you were told in the comment, dynamic () has to go outside of the component or screen you are going to return, e. g.

import dynamic from "next/dynamic"

const MyAwesomeMap = dynamic(() => import("../components/Map/index"), { ssr:false })

export default function inicio() {

return(
 <>
  <p>Example Map</p>
  <MyAwesomeMap />
 </>
 )
}
Schnook answered 29/6, 2021 at 18:26 Comment(1)
Still getting error even if i put outside the component, i don't know where is the problemHypertrophy
B
2

First of all, we need to check if the Map component created using react-leaflet is mounted or not,

  const LeafletMap = () => {
  const [isMounted, setIsMounted] = React.useState(false);

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

  return (
    isMounted && (
      <MapContainer>...</MapContainer>)}

After this step, then dynamically import the map component created as below,

const Container = () => {
  const Map = React.useMemo(
    () => dynamic(() => import("./LeafletMap"), { ssr: false }),
    []
  );
  return (
    <ContainerDiv>
      <HeaderBar />
      <Map />
    </ContainerDiv>
  );
};

And finally, make sure the leaflet css is imported in _app.js file as below,

import "leaflet/dist/leaflet.css";

const App = ({ Component, pageProps }) => {
  return <Component {...pageProps} />;
};

export default App;

After these changes the leaflet map should render without any issue.

Bootlick answered 18/3, 2023 at 10:22 Comment(0)
S
1

In Next.js 14, I encountered a "window is not defined" error when using React-Leaflet. I resolved it by dynamically importing the Map component with ssr: false to disable server-side rendering. Here's the code that fixed it:

"use client";

import dynamic from "next/dynamic";

const Map = dynamic(() => import("./_components/Map"), { ssr:false });

const App = () => {
  return <Map />;
};

export default App;
Swan answered 16/8 at 14:32 Comment(0)
G
0

If you get type error than you can configure something like this

  const MapWithNoSSR = dynamic(() => import('./Leaflet').then((module: any) => module.Leaflet), {
    ssr: false,
  });
Gondar answered 13/6, 2023 at 9:55 Comment(0)
T
-1

Your Map component doesn't return anything

Tradein answered 7/10, 2021 at 7:45 Comment(1)
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Planometer
P
-1

Move your Map component out of the Pages directory and into a separate Components directory.

Nextjs likes to pre-compile the pages directory to collect metadata at build time. https://nextjs.org/docs/basic-features/pages

Perverted answered 21/4, 2023 at 4:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.