Markers and custom icons
Quick answer
This tutorial explains why the default Leaflet marker icon often disappears and how L.Icon.Default.imagePath fixes the generated URL. It walks through the L.icon options iconUrl, iconSize, iconAnchor, popupAnchor and shadowUrl, then builds HTML markers with L.divIcon for numbers and status badges. It also covers rotationAngle, rotateOrigin, draggable, riseOnHover and zIndexOffset, so readers can ship branded, interactive pins.
Key points
- Set L.Icon.Default.imagePath when Leaflet is loaded from a CDN or a rewritten dist folder.
- Always supply iconAnchor so the pin tip, not the top-left corner, sits on the coordinate.
- Use L.divIcon with escaped HTML for numbered or status markers instead of image files.
Example
<link rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/leaflet@1.9.4/dist/leaflet.css">
<script src="https://cdn.jsdelivr.net/npm/leaflet@1.9.4/dist/leaflet.js"></script>
<script>
L.Icon.Default.imagePath = 'https://cdn.jsdelivr.net/npm/leaflet@1.9.4/dist/images/';
var map = L.map('map').setView([39.907359, 116.391263], 12);
</script>var pin = L.icon({
iconUrl: 'https://unpkg.com/leaflet@1.9.4/dist/images/marker-icon.png',
shadowUrl: 'https://unpkg.com/leaflet@1.9.4/dist/images/marker-shadow.png',
iconSize: [25, 41],
iconAnchor: [12, 41], // 底部尖端对准坐标
popupAnchor: [1, -34],
shadowSize: [41, 41]
});
L.marker([39.907359, 116.391263], { icon: pin })
.bindPopup('天安门')
.addTo(map);
Notes
- A wrong default icon path fails silently; the marker element exists but nothing is painted.
- iconSize is in CSS pixels, so a 2x image must still use the design size, not double it.
English edition written for Atlaslog. Code is taken from the original Chinese page and runs unchanged.
Atlaslog (2026). Markers and custom icons. https://www.jingweizhi.com/en/leaflet/tutorials/markers-icons.html (accessed 2026-11-03).