When I try to use custom marker icons with leaflet, building fails. Everything works in development, but when I run next build, I get: ReferenceError: window is not defined
.
Here’s my code for the Leaflet map:
"use client";
import React from "react";
import { EnrichedPrice } from "@/types/enriched_price";
import dynamic from "next/dynamic";
import Load from "@/components/Load";
import { Icon } from "leaflet";
import { useRouter } from "next/navigation";
// Dynamically import MapContainer to avoid SSR issues
const MapContainer = dynamic(
() => import("react-leaflet").then((mod) => mod.MapContainer),
{ ssr: false }
);
const TileLayer = dynamic(
() => import("react-leaflet").then((mod) => mod.TileLayer),
{ ssr: false }
);
const Marker = dynamic(
() => import("react-leaflet").then((mod) => mod.Marker),
{ ssr: false }
);
const Popup = dynamic(() => import("react-leaflet").then((mod) => mod.Popup), {
ssr: false,
});
const customIcon = new Icon({
iconUrl: "/marker.png",
iconSize: [28, 45],
iconAnchor: [12, 41],
popupAnchor: [1, -34],
shadowSize: [41, 41],
});
export default function ResortMap({
prices,
loading,
}: {
prices: EnrichedPrice[];
loading: boolean;
}) {
const router = useRouter();
if (loading) return <Load />;
return (
<div className="h-[80vh] w-full p-4">
<MapContainer
center={[39.8283, -98.5795]} // Center of US
zoom={4}
className="w-full h-full rounded-lg"
scrollWheelZoom={true}
>
<TileLayer
attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
{prices.map((price) => (
<Marker
key={price.id}
position={[price.location.lat, price.location.lng]}
icon={customIcon}
eventHandlers={{
click: () => router.push(price.links),
mouseover: (e) => e.target.openPopup(),
mouseout: (e) => e.target.closePopup(),
}}
>
<Popup className="font-roboto">
<div className="flex items-center justify-between gap-2">
<div className="font-bold">{price.resort_name}</div>
<div className="text-sky-500 font-extrabold">
{price.price === -1 ? (
<span className="text-red-500">Unavailable</span>
) : (
`$${price.price}`
)}
</div>
</div>
</Popup>
</Marker>
))}
</MapContainer>
</div>
);
}
I’ve tried a few different things, but most were for the default marker and none of them worked. I know it’s the icon, because when I comment out the icon assignment, building goes smoothly. Does anyone have any ideas? Thanks!