I want to display a leaflet map in a NextJS 14 App. Trying to make it work poses these challenges:
"next": "14",
"react": "18",
"react-leaflet": "4",
What's the setup for a minimal working configuration?
I searched Stackoverflow and Github for good solutions. I eventually found everything I needed to know, but it took some time to gather all the information.
Thus, I'd like to provide all the necessary information in one post.
To make this work, we need leaflet-defaulticon-compatibility. The full setup looks like this:
npx create-next-app@latest
npm install leaflet react-leaflet leaflet-defaulticon-compatibility
npm install -D @types/leaflet
Import css and js for leaflet
and leaflet-defaulticon-compatibility
. The order is important! Create a map component and make sure to set width and height on it.
"use client";
// START: Preserve spaces to avoid auto-sorting
import "leaflet/dist/leaflet.css";
import "leaflet-defaulticon-compatibility/dist/leaflet-defaulticon-compatibility.webpack.css";
import "leaflet-defaulticon-compatibility";
// END: Preserve spaces to avoid auto-sorting
import { MapContainer, Marker, Popup, TileLayer } from "react-leaflet";
## components/Map.tsx
```export default function Map() {
return (
<MapContainer
preferCanvas={true}
center={[51.505, -0.09]}
zoom={11}
scrollWheelZoom={true}
style={{ height: "400px", width: "600px" }}
>
<TileLayer
attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
<Marker position={[51.505, -0.09]}>
<Popup>
This Marker icon is displayed correctly with <i>leaflet-defaulticon-compatibility</i>.
</Popup>
</Marker>
</MapContainer>
);
}
Import the map component:
"use client";
import dynamic from "next/dynamic";
const LazyMap = dynamic(() => import("@/components/Map"), {
ssr: false,
loading: () => <p>Loading...</p>,
});
export default function Home() {
return (
<main>
<LazyMap />
</main>
);
}
1
comment -- RaNii Johnson Feb 22, 2024 at 10:20:23
2
comsss -- RaNii Johnson Feb 22, 2024 at 10:20:33
3
"use client"; import dynamic from "next/dynamic"; const LazyMap = dynamic(() => import("@/components/Map"), { ssr: false, loading: () => <p>Loading...</p>, }); export default function Home() { return ( <main> <LazyMap /> </main> ); } -- RaNii Johnson Feb 22, 2024 at 10:23:05