I am trying to render Leaflet
maps in Next.js using Typescript. I read that ssr needed to be disabled to avoid the 'window not defined' problem, but when trying this to generate the map:
import React from "react";
import { MapContainer, TileLayer } from "react-leaflet";
export const Leaflet: React.FC = () => {
return (
<MapContainer center={{ lat: 48.71291, lng: 44.52693 }} zoom={13}>
<TileLayer
attribution='© <a href="http://osm.org/copyright%22%3EOpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
</MapContainer>
);
};
and this to render it:
const Home: NextPage = () => {
const MapWithNoSSR = dynamic(() => import("../components/Leaflet"), {
ssr: false,
});
return (
<>
<MapWithNoSSR/>
</>
);
};
export default Home
TypesSript gives me this error:
Argument of type '() => Promise<typeof import("/src/components/Leaflet")>' is not assignable to parameter of type 'DynamicOptions<{}> | Loader<{}>'. Type '() => Promise<typeof import("/src/components/Leaflet")>' is not assignable to type '() => LoaderComponent<{}>'.
And the browser gives this error:
Error: Element type is invalid. Received a promise that resolves to: [object Module]. Lazy element type must resolve to a class or function.
Has anyone here experienced something similar and have some advice regarding how to solve it?
You are getting those errors because your Leaflet
component is a named module, and you are trying to access it as if it was a default one. Change your code to as the doc says:
import { NextPage } from "next";
import dynamic from "next/dynamic";
// ⚠️: .then() is needed because the component is not exported with the default keyword
const MapWithNoSSR = dynamic(
() => import("../components/Leaflet").then((module) => module.Leaflet),
{
ssr: false,
}
);
const Home: NextPage = () => {
return (
<>
<MapWithNoSSR />
</>
);
};
export default Home;
Also, notice I pushed the dynamic import outside of Home
.