Display a remote SVG symbol
Uses the 'styleimagemissing' event to load a remote image and use it.
<!DOCTYPE html>
<html lang="en">
<head>
<title>Display a remote SVG symbol</title>
<meta property="og:description" content="Uses the 'styleimagemissing' event to load a remote image and use it." />
<meta charset='utf-8'>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel='stylesheet' href='https://unpkg.com/maplibre-gl@5.9.0/dist/maplibre-gl.css' />
<script src='https://unpkg.com/maplibre-gl@5.9.0/dist/maplibre-gl.js'></script>
<style>
body { margin: 0; padding: 0; }
html, body, #map { height: 100%; }
</style>
</head>
<body>
<div id="map"></div>
<script>
const map = new maplibregl.Map({
container: 'map', // container id
style: 'https://demotiles.maplibre.org/style.json', // style URL
center: [0, 0], // starting position [lng, lat]
zoom: 1, // starting zoom
maplibreLogo: true
});
map.on('load', () => {
const existingImages = {};
map.on('styleimagemissing', async (e) => {
if (existingImages[e.id]) {
return;
}
existingImages[e.id] = true;
const response = await fetch(e.id);
const svgText = await response.text();
const svg = 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(svgText);
const image = new Image();
const promise = new Promise((resolve) => {
image.onload = resolve;
});
image.src = svg;
await promise; // Wait for the image to load
map.addImage(e.id, image);
});
map.addSource('point', {
'type': 'geojson',
'data': {
'type': 'FeatureCollection',
'features': [
{
'type': 'Feature',
'geometry': {
'type': 'Point',
'coordinates': [0, 0]
},
},
]
}
});
map.addLayer({
'id': 'svg-symbol',
'type': 'symbol',
'source': 'point',
'layout': {
'icon-image': 'https://maplibre.org/maplibre-gl-js/docs/assets/logo.svg',
'icon-overlap': 'always',
'text-overlap': 'always'
}
});
});
</script>
</body>
</html>