Atlaslog / Field Notes / Leaflet containers & layers
Field note · Leaflet containers & layers
Marker icons break after bundling because paths are lost
Quick answer
L.Icon.Default derives its image path at runtime, but the bundler renames and moves the PNGs into /assets with a content hash, so the marker, retina marker and shadow all 404. Local dev works because paths are still literal.
Symptom
- GET https://example.cn/marker-icon.png 404 plus marker-icon-2x.png and marker-shadow.png 404.
- Every marker shows the browser broken-image glyph at the correct location.
- The built file actually exists at /assets/marker-icon-abc123.png.
Checklist
- Print L.Icon.Default.prototype.options and _getIconUrl('icon') to see the resolved URL.
- Compare the resolved name with the real filename under dist/assets.
- Check whether the app is served from a sub-path such as /app/.
- Check whether the bundler config emits Leaflet images at all.
Fix
Delete _getIconUrl and mergeOptions with absolute iconUrl, iconRetinaUrl and shadowUrl (iconSize 25x41, iconAnchor [12, 41]), or import the PNG URLs from leaflet/dist/images and pass them to mergeOptions.
Code
GET https://example.cn/marker-icon.png 404 (Not Found)
GET https://example.cn/marker-icon-2x.png 404 (Not Found)
GET https://example.cn/marker-shadow.png 404 (Not Found)console.log(L.Icon.Default.prototype.options);
console.log(L.Icon.Default.prototype._getIconUrl('icon'));
// https://example.cn/marker-icon.png
Watch out
- Using ./marker-icon.png resolves against the current route and 404s on every nested page.
- Copying the images to the site root works until the app is deployed under a sub-path.
English edition written for Atlaslog from the original Chinese field note. Code is unchanged and runs as-is.
Atlaslog (2026). Marker icons break after bundling because paths are lost. https://www.jingweizhi.com/en/cookbook/leaflet-marker-icon-404.html (accessed 2026-11-03).