Work with markers in Mapbox.js
Mapbox.js is no longer in active development. To learn more about our newer mapping tools see Add custom markers in Mapbox GL JS.
In this guide, we’ll show how to add markers, customize them, and make them interactive with Mapbox.js. Think of this guide as a curated stroll through all that’s possible with markers in Mapbox.js.
Getting started
For this guide you'll need your API access token. You can find your access token on your Account page. To better understand each example, you can copy the full source code into your own local project and experiment. We adapted many of these demos from Mapbox.js examples.
Add markers
You can add markers to your map using Leaflet or with GeoJSON using Mapbox.js.
Add markers in Leaflet
You can add a DOM marker to your map with L.marker. In the example below, we added a marker to the map by knowing its coordinates. Use this technique when you have only a few markers to add.
<div id='map-leaflet' class='map'></div>
<script>
const mapLeaflet = L.mapbox.map('map-leaflet')
.setView([37.8, -96], 4)
.addLayer(L.mapbox.styleLayer('mapbox://styles/mapbox/light-v11'));
L.marker([38.913184, -77.031952]).addTo(mapLeaflet);
L.marker([37.775408, -122.413682]).addTo(mapLeaflet);
mapLeaflet.scrollWheelZoom.disable();
</script>
Add markers with GeoJSON in Mapbox.js
You can also save your marker coordinates as GeoJSON and then load your GeoJSON on a map with Mapbox.js. In this example, we added the coordinates of the Mapbox D.C. and San Francisco offices to our inline GeoJSON. The GeoJSON format organizes features, especially when working with larger data files.
<div id='map_geo' class='map'></div>
<script>
const geojson = [
{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [-77.031952, 38.913184]
}
},
{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [-122.413682, 37.775408]
}
}
];
const mapGeo = L.mapbox.map('map_geo')
.setView([37.8, -96], 4)
.addLayer(L.mapbox.styleLayer('mapbox://styles/mapbox/light-v11'));
const myLayer = L.mapbox.featureLayer().setGeoJSON(geojson).addTo(mapGeo);
mapGeo.scrollWheelZoom.disable();
</script>
You can also load GeoJSON as an external file hosted locally or on GitHub. In the next section, you'll learn how to style GeoJSON markers with the simplestyle specification.
If you're new to working with GeoJSON, here are some tools to help you generate, validate, or format GeoJSON:
- geojson.io — create and customize GeoJSON.
geojsonhint
— validate GeoJSON with this lint tool.- toGeoJSON — convert a KML or GPX file to GeoJSON.
- csv2geojson — convert a CSV file to GeoJSON.
Style markers
To style a marker, you can add simplestyle to your GeoJSON, load a custom image, or create your own markers with HTML and CSS.
Style markers with simplestyle
The simplestyle spec is a styling convention for GeoJSON. This means that you can add specific keys and values to each marker to change a marker's color, symbol, and size.
Here are all the styling options available as keys and values:
Key | Value | Example |
---|---|---|
"marker-color" | Any hex value Example: "#3bb2d0" | |
"marker-symbol" | Any Maki icon name, an integer, or a lowercase letter Example: "1" | |
"marker-size" | small, medium, large Example: "large" |
In this example, we took the GeoJSON from the previous section and added simplestyle. View the source to see how the marker styles are added to each feature.
<div id='map_simple' class='map'></div>
<script>
const geojson = [
{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [-77.031952, 38.913184]
},
properties: {
'marker-color': '#3bb2d0',
'marker-size': 'large',
'marker-symbol': 'rocket'
}
},
{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [-122.413682, 37.775408]
},
properties: {
'marker-color': '#3bb2d0',
'marker-size': 'large',
'marker-symbol': 'rocket'
}
}
];
const mapSimple = L.mapbox.map('map_simple')
.setView([37.8, -96], 4)
.addLayer(L.mapbox.styleLayer('mapbox://styles/mapbox/light-v11'));
const myLayer = L.mapbox.featureLayer().setGeoJSON(geojson).addTo(mapSimple);
mapSimple.scrollWheelZoom.disable();
</script>
Style markers with an image
You can define a custom marker image in your GeoJSON by adding an icon
object to each feature's properties
. In this example, L.icon is used to set the marker image to each feature's iconURL
.
<div id='map-one' class='map'></div>
<script>
const mapOne = L.mapbox.map('map-one')
.setView([37.8, -96], 4)
.addLayer(L.mapbox.styleLayer('mapbox://styles/mapbox/light-v11'));
const myLayer = L.mapbox.featureLayer().addTo(mapOne);
const geojson = [
{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [-77.031952, 38.913184]
},
properties: {
icon: {
iconUrl: 'https://docs.mapbox.com/mapbox.js/assets/images/astronaut1.png',
iconSize: [50, 50], // size of the icon
iconAnchor: [25, 25], // point of the icon which will correspond to marker's location
popupAnchor: [0, -25], // point from which the popup should open relative to the iconAnchor
className: 'dot'
}
}
},
{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [-122.413682, 37.775408]
},
properties: {
icon: {
iconUrl: 'https://docs.mapbox.com/mapbox.js/assets/images/astronaut2.png',
iconSize: [50, 50], // size of the icon
iconAnchor: [25, 25], // point of the icon which will correspond to marker's location
popupAnchor: [0, -25], // point from which the popup should open relative to the iconAnchor
className: 'dot'
}
}
}
];
myLayer.on('layeradd', (event) => {
event.layer.setIcon(L.icon(event.layer.feature.properties.icon));
});
myLayer.setGeoJSON(geojson);
mapOne.scrollWheelZoom.disable();
</script>
Style markers with HTML and CSS
If you'd like to customize your markers even more, you can replace the standard marker with a <div>
, assign it a class, and then style it with CSS using L.divIcon. In this example, you'll follow a similar pattern as you did when adding a marker image, but instead you'll assign a class name to the features and then add CSS to style it.
<style>
.my-icon {
border-radius: 100%;
width: 20px;
height: 20px;
text-align: center;
line-height: 20px;
color: white;
}
.icon-dc {
background: #3bb2d0;
}
.icon-sf {
background: #3bb2d0;
}
</style>
<div id='map-two' class='map'></div>
<script>
const mapTwo = L.mapbox.map('map-two')
.setView([37.8, -96], 4)
.addLayer(L.mapbox.styleLayer('mapbox://styles/mapbox/light-v11'));
const myLayer = L.mapbox.featureLayer().addTo(mapTwo);
const geojson = [
{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [-77.031952, 38.913184]
},
properties: {
icon: {
className: 'my-icon icon-dc', // class name to style
html: '★', // add content inside the marker, in this case a star
iconSize: null // size of icon, use null to set the size in CSS
}
}
},
{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [-122.413682, 37.775408]
},
properties: {
icon: {
className: 'my-icon icon-sf', // class name to style
html: '★', // add content inside the marker, in this case a star
iconSize: null // size of icon, use null to set the size in CSS
}
}
}
];
myLayer.on('layeradd', (event) => {
event.layer.setIcon(L.divIcon(event.layer.feature.properties.icon));
});
myLayer.setGeoJSON(geojson);
mapTwo.scrollWheelZoom.disable();
</script>
Add popups
You can add popups with simplestyle in your GeoJSON or with JavaScript.
Add popups with simplestyle
Simplestyle allows you to add popups automatically if you add title
and description
keys to each feature's properties. In the example below, these fields are added to the GeoJSON. Click the markers to trigger the popup.
<div id='map-popups' class='map'></div>
<script>
const mapPopups = L.mapbox.map('map-popups')
.setView([37.8, -96], 4)
.addLayer(L.mapbox.styleLayer('mapbox://styles/mapbox/light-v11'));
const myLayer = L.mapbox.featureLayer().addTo(mapPopups);
const geojson = [
{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [-77.031952, 38.913184]
},
properties: {
title: 'Mapbox DC',
description: '1714 14th St NW, Washington DC',
'marker-color': '#3bb2d0',
'marker-size': 'large',
'marker-symbol': 'rocket'
}
},
{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [-122.413682, 37.775408]
},
properties: {
title: 'Mapbox SF',
description: '155 9th St, San Francisco',
'marker-color': '#3bb2d0',
'marker-size': 'large',
'marker-symbol': 'rocket'
}
}
];
myLayer.setGeoJSON(geojson);
mapPopups.scrollWheelZoom.disable();
</script>
You can add HTML to you popups by adding it to the title
and description
values in your GeoJSON. This allows you to add links, images, videos, lists, and other HTML elements to your popups.
Add popups with JavaScript
You can customize the content of each popup with the L.bindPopup method. In this example, an image
key is added to each feature's property object, and a reference to this key when is included when bindPopup()
is called to make the image appear inside the popup.
<div id='map-popups-js' class='map'></div>
<script>
const mapPopupsJS = L.mapbox.map('map-popups-js')
.setView([37.8, -96], 4)
.addLayer(L.mapbox.styleLayer('mapbox://styles/mapbox/light-v11'));
const myLayer = L.mapbox.featureLayer().addTo(mapPopupsJS);
const geojson = [
{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [-77.031952, 38.913184]
},
properties: {
title: 'Mapbox DC',
description: '1714 14th St NW, Washington DC',
image: 'https://farm9.staticflickr.com/8604/15769066303_3e4dcce464_n.jpg',
icon: {
iconUrl: 'https://docs.mapbox.com/mapbox.js/assets/images/astronaut1.png',
iconSize: [50, 50], // size of the icon
iconAnchor: [25, 25], // point of the icon which will correspond to marker's location
popupAnchor: [0, -25], // point from which the popup should open relative to the iconAnchor
className: 'dot'
}
}
},
{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [-122.413682, 37.775408]
},
properties: {
title: 'Mapbox SF',
description: '155 9th St, San Francisco',
image: 'https://farm9.staticflickr.com/8571/15844010757_63b093d527_n.jpg',
icon: {
iconUrl: 'https://docs.mapbox.com/mapbox.js/assets/images/astronaut2.png',
iconSize: [50, 50], // size of the icon
iconAnchor: [25, 25], // point of the icon which will correspond to marker's location
popupAnchor: [0, -25], // point from which the popup should open relative to the iconAnchor
className: 'dot'
}
}
}
];
// Set a custom icon on each marker based on feature properties.
myLayer.on('layeradd', (event) => {
event.layer.setIcon(L.icon(event.layer.feature.properties.icon));
const content = `<p><strong>${layer.feature.properties.title}</strong></p><img src='${layer.feature.properties.image}' alt=''>`;
layer.bindPopup(content);
});
myLayer.setGeoJSON(geojson);
mapPopupsJS.scrollWheelZoom.disable();
</script>
More examples
You can further customize your popups with Mapbox.js. Here are more examples to get you started:
- Add an image gallery to a popup
- Show popup outside of the marker
- Embed a video in a popup
- Embed an audio clip in a popup
- Tabs in popups
- Style popups with CSS
Cluster markers
For dense point data, try the Leaflet plug-in Markercluster to visualize your data. In the example below, we load an external GeoJSON file, create a clustergroup
from the data, and add it to the map. Since Markercluster is a plugin, you'll need to add additional CSS and JS to enable it.
<script src='https://api.mapbox.com/mapbox.js/plugins/leaflet-markercluster/v3.2.1/leaflet.markercluster.js'></script>
<link href='https://api.mapbox.com/mapbox.js/plugins/leaflet-markercluster/v3.2.1/MarkerCluster.css' rel='stylesheet' />
<link href='https://api.mapbox.com/mapbox.js/plugins/leaflet-markercluster/v3.2.1/MarkerCluster.Default.css' rel='stylesheet' />
<div id='map-cluster' class='map'></div>
<script>
const mapCluster = L.mapbox.map('map-cluster')
.setView([38.9, -77], 11)
.addLayer(L.mapbox.styleLayer('mapbox://styles/mapbox/light-v11'));
L.mapbox.featureLayer()
.loadURL('/help/data/stations.geojson')
.on('ready', (event) => {
const clusterGroup = new L.MarkerClusterGroup();
event.target.eachLayer((layer) => clusterGroup.addLayer(layer));
mapCluster.addLayer(clusterGroup);
});
mapCluster.scrollWheelZoom.disable();
</script>
More examples
For more ideas of what you can do with clusters in Mapbox.js, explore these examples:
- Multiple differently styled clusters
- Clusters with custom polygon appearance
- Clusters with custom cluster icons
Toggle layers
Finally, take a look at how to toggle layers in Mapbox.js. You can help users sift through your markers by adding filters to let them turn layers on and off. In this example, the script automatically creates a toggle option for each transit line and will only add a new layer to the toggle list if its line
is declared in the GeoJSON.
<style>
.filter-ui {
background: #fff;
position: absolute;
top: 10px;
right: 10px;
z-index: 100;
padding: 10px;
border-radius: 3px;
}
.filter-ui input {
vertical-align: middle;
}
</style>
<nav id='filters' class='filter-ui'></nav>
<div id='map-toggle' class='map'></div>
<script>
const mapToggle = L.mapbox.map('map-toggle')
.setView([38.9, -77], 11)
.addLayer(L.mapbox.styleLayer('mapbox://styles/mapbox/light-v11'));
const filters = document.getElementById('filters');
const markers = L.mapbox.featureLayer().loadURL('/help/data/examples/stations.geojson');
markers.on('ready', (event) => {
const typesObj = {},
types = [];
const features = event.target._geojson.features;
for (const feature of features) {
typesObj[feature.properties.line] = true;
}
for (const key in typesObj) {
if ({}.hasOwnProperty.call(typesObj, key)) {
types.push(key);
}
}
const checkboxes = [];
for (const type of types) {
const item = filters.appendChild(document.createElement('div'));
const checkbox = item.appendChild(document.createElement('input'));
const label = item.appendChild(document.createElement('label'));
checkbox.type = 'checkbox';
checkbox.id = type;
checkbox.checked = true;
label.innerHTML = `${type}`;
label.setAttribute('for', type);
checkbox.addEventListener('change', update);
checkboxes.push(checkbox);
}
function update() {
const enabled = {};
for (const checkbox of checkboxes) {
if (checkbox.checked) enabled[checkbox.id] = true;
}
markers.setFilter((feature) => feature.properties.line in enabled);
}
}).addTo(mapToggle);
mapToggle.scrollWheelZoom.disable();
</script>
More examples
For more ideas on how to filter or toggle your markers, explore these examples:
Next steps
You now have the tools, code, and inspiration to add any markers you need to your map. For more ways to extend your Mapbox.js project, explore the Build a store locator tutorial.