Skip to main content

Add custom vector icons

Experimental Feature

Note that this is an experimental feature which is under development and is subject to change.

You can add custom vector icons with dynamically defined color. For that you need to upload SVG icon image in Mapbox Studio with defined dynamic color parameters. Example of such SVG used in the next code snippet:

<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg" xmlns:m="https://www.mapbox.com">
<m:metadata>
<m:parameters>
<m:parameter m:type="color" m:name="flag_color" m:value="#000000"/>
</m:parameters>
</m:metadata>
<path d="M10.1418 27.3334L10.1417 4.12779C10.401 4.00292 10.5826 3.73252 10.5826 3.41689V1.78416C10.5826 1.35152 10.2441 1 9.82689 1H8.56725C8.14958 1 7.81108 1.35152 7.81108 1.78416V3.41689C7.81108 3.73301 7.99218 4.00292 8.25198 4.12779L8.25206 27.3334C6.01343 27.5064 4 28.2935 4 29.6485C4 31.1927 6.61409 32 9.19692 32C11.7793 32 14.3938 31.1922 14.3938 29.6485C14.3938 28.2935 12.3799 27.505 10.1418 27.3334ZM9.19692 30.8235C6.55768 30.8235 5.13401 29.9897 5.13401 29.6475C5.13401 29.3496 6.22013 28.6751 8.25206 28.5094V29.6475H10.1418V28.5094C12.1742 28.676 13.2598 29.3496 13.2598 29.6475C13.2598 29.9897 11.8362 30.8235 9.19692 30.8235ZM28 13.9994C28 14.0205 27.9962 14.0407 27.9938 14.0603C28.0038 14.1473 27.9981 14.2363 27.9678 14.3238C27.9483 14.3824 27.4638 15.7737 25.9633 16.2801C25.6073 16.4005 25.2275 16.461 24.8269 16.461C23.5403 16.461 22.0261 15.843 20.3075 14.6134C15.3263 11.0515 12.2945 14.3814 12.1674 14.5244C12.0096 14.7034 11.7612 14.7639 11.5431 14.6763C11.3255 14.5888 11.1809 14.3725 11.1809 14.1296V3.74333C11.1809 3.73448 11.1828 3.72613 11.1832 3.71678C11.1823 3.69663 11.188 3.67795 11.1889 3.65779C11.1908 3.64402 11.1918 3.63026 11.1946 3.61747C11.207 3.49948 11.2439 3.38296 11.3264 3.28808C11.3639 3.24481 15.1281 -0.968021 20.9513 3.19762C22.8718 4.57076 24.4828 5.09484 25.612 4.71382C26.5692 4.39033 26.8949 3.49604 26.8973 3.4867C26.9888 3.21679 27.2538 3.05258 27.5278 3.10175C27.8004 3.14944 27.9995 3.39476 27.9995 3.68188L28 13.9994Z" fill="#000000"/>
</svg>

Don't forget to add the m: XML namespace to the SVG element: xmlns:m="https://www.mapbox.com". All required metadata attributes should be placed inside the m:metadata element. All dynamic parameters for vector icons should be stored in m:parameters element. For colors, use m:parameter elements with m:type="color", and place them inside the m:parameters element. You cannot use multiple m:name attributes for the same color value, as this may cause conflicts.

In the provided example, we uploaded the SVG icon to the Studio with the name flag, including the defined metadata attributes required for color customization.

To customize the color of the icon, you can use the second parameter of the icon-image expression. The second parameter is an object that can contains params dictionary, where you can specify colors. The color values can be specified as a static value or as an expression. In this example, the color of the icon changes based on the feature property flagColor.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Add custom vector icons</title>
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
<link href="https://api.mapbox.com/mapbox-gl-js/v3.9.2/mapbox-gl.css" rel="stylesheet">
<script src="https://api.mapbox.com/mapbox-gl-js/v3.9.2/mapbox-gl.js"></script>
<style>
body { margin: 0; padding: 0; }
#map { position: absolute; top: 0; bottom: 0; width: 100%; }
</style>
</head>
<body>
<div id="map"></div>

<script>
// TO MAKE THE MAP APPEAR YOU MUST
// ADD YOUR ACCESS TOKEN FROM
// https://account.mapbox.com
mapboxgl.accessToken = 'YOUR_MAPBOX_ACCESS_TOKEN';
const geojson = {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
properties: {
flagColor: 'red'
},
geometry: {
type: 'Point',
coordinates: [24.68727, 60.185755]
}
},
{
type: 'Feature',
properties: {
flagColor: 'yellow'
},
geometry: {
type: 'Point',
coordinates: [24.68827, 60.186255]
}
},
{
type: 'Feature',
properties: {
flagColor: '#800080'
},
geometry: {
type: 'Point',
coordinates: [24.68927, 60.186055]
}
}
]
};

const map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox-map-design/cm4r19bcm00ao01qvhp3jc2gi',
center: [24.68727, 60.185755],
zoom: 16
});

map.once('load', () => {
map.addSource('points', {
type: 'geojson',
data: geojson
});

map.addLayer({
id: 'points',
type: 'symbol',
source: 'points',
layout: {
'icon-image': [
'image',
'flag',
{ params: { flag_color: ['get', 'flagColor'] } }
]
}
});
});
</script>

</body>
</html>
This code snippet will not work as expected until you replace YOUR_MAPBOX_ACCESS_TOKEN with an access token from your Mapbox account.
Was this example helpful?