I've observed that the leaflet component fails to load whenever I include the Leaflet CSS file, regardless of what I try. I’ve also noticed a strange behavior where the map loads when I remove the leaflet.css import from my Leaflet.tsx file, but it appears completely scattered and unorganized. It seems that the absence of the CSS affects the map’s proper rendering, causing layout issues. However, including the CSS prevents the component from loading entirely and I am faced with a blank component, which is equally problematic.
Leaflet.tsx
'use client';
import React from 'react';
import {
MapContainer,
TileLayer,
Marker,
Popup,
useMapEvents,
} from 'react-leaflet';
import { useState } from 'react';
import 'leaflet/dist/leaflet.css';
import 'leaflet-defaulticon-compatibility';
import 'leaflet-defaulticon-compatibility/dist/leaflet-defaulticon-compatibility.css';
const Leaflet = () => {
function LocationMarker() {
const [position, setPosition] = useState<L.LatLng | null>(null);
const map = useMapEvents({
click() {
map.locate();
},
locationfound(e) {
setPosition(e.latlng);
map.flyTo(e.latlng, map.getZoom());
},
});
return position === null ? null : (
<Marker position={position}>
<Popup>You are here</Popup>
</Marker>
);
}
return (
<MapContainer
center={[51.505, -0.09]}
zoom={13}
scrollWheelZoom={false}
>
<TileLayer
attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
url='https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'
/>
<LocationMarker />
</MapContainer>
);
};
export default Leaflet;
Dynamic import into my component
const LeafletMap = useMemo(
() =>
dynamic(() => import('@/components/Leaflet'), {
loading: () => <p>A map is loading</p>,
ssr: false,
}),
[],
);
The config seems alright, what you are missing though is the height
style on the MapContainer
. Without it, the map will display incorrectly.
So, it should look like this:
'use client';
import React from 'react';
import {
MapContainer,
TileLayer,
Marker,
Popup,
useMapEvents,
} from 'react-leaflet';
import { useState } from 'react';
import 'leaflet/dist/leaflet.css';
import 'leaflet-defaulticon-compatibility';
import 'leaflet-defaulticon-compatibility/dist/leaflet-defaulticon-compatibility.css';
const Leaflet = () => {
function LocationMarker() {
const [position, setPosition] = useState<L.LatLng | null>(null);
const map = useMapEvents({
click() {
map.locate();
},
locationfound(e) {
setPosition(e.latlng);
map.flyTo(e.latlng, map.getZoom());
},
});
return position === null ? null : (
<Marker position={position}>
<Popup>You are here</Popup>
</Marker>
);
}
return (
<MapContainer
style={{ height: "250px" }} // <- important part
center={[51.505, -0.09]}
zoom={13}
scrollWheelZoom={false}
>
<TileLayer
attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
url='https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'
/>
<LocationMarker />
</MapContainer>
);
};
export default Leaflet;
The requirement is mentioned on the react-leaflet page, and on the leaflet page