Add custom markers in Mapbox GL JS
In this tutorial, you will learn how to build an interactive web map that adds custom markers at specified locations using Mapbox GL JS. You will also add informative popups when a user clicks one of these markers.
Your final map will look like this:
Prerequisites
To follow along with this guide you'll need:
- Front-end familiarity: Some familiarity with front-end development (HTML, CSS, and JavaScript)
- Mapbox account: Sign up or log into a free account at account.mapbox.com.
- IDE / Code editor: A program like Visual Studio or Sublime Text to edit your HTML file.
We also recommend you view the related video tutorial for additional guidance.
If you wish to copy the code sample in its entirety instead of following along with the tutorial, view the code snippet at the bottom of the page.
Step 1: Create an HTML file
Create a new HTML file and name it index.html
.
Step 2: Initialize your map
Initialize your map by adding code to your index.html
file.
- Open your
index.html
file in your code editor. - Copy and paste the code below into your file.
- Once pasted, check that
mapboxgl.accessToken
is assigned to your public access token. This value should start withpk
.- If you see
YOUR_MAPBOX_ACCESS_TOKEN
, log into your account and copy the code snippet again. Your token is automatically added to your code snippet when you're logged in.
- If you see
- Open your
index.html
file in a browser and you should be able to see the default mapbox globe.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Add custom markers in Mapbox GL JS</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link
href="https://fonts.googleapis.com/css?family=Open+Sans"
rel="stylesheet"
/>
<script src="https://api.tiles.mapbox.com/mapbox-gl-js/v3.3.0/mapbox-gl.js"></script>
<link
href="https://api.tiles.mapbox.com/mapbox-gl-js/v3.3.0/mapbox-gl.css"
rel="stylesheet"
/>
<style>
body {
margin: 0;
padding: 0;
}
#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
<!--code from step 5-3 will go here!-->
<!--code from step 7 will go here!-->
</style>
</head>
<body>
<div id="map"></div>
<script>
mapboxgl.accessToken = 'YOUR_MAPBOX_ACCESS_TOKEN';
//code from step 3 will go here
const map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/light-v11',
center: [-96, 37.8],
zoom: 3
});
//code from step 4 will go here
</script>
</body>
</html>
As you can see above, the Mapbox GL JS Map
is instantiated with several options defined:
container
: theid
of the<div>
element on the page where the map should live. In this case, theid
for the<div>
is'map'
.style
: the style URL for the map style. In this case, use the Mapbox Light map which has the style URLmapbox://styles/mapbox/light-11
.center
: the initial centerpoint of the map in[longitude, latitude]
format.zoom
: the initial zoom level of the map.
Step 3: Load GeoJSON data
Next let's determine where your markers will appear on the map by creating a GeoJSON object.
GeoJSON is a web-friendly spatial data format that can store geometries such as Points, Linestrings, and Polygons, and their associated data properties. We can use Point data in GeoJSON format to determine where our markers will be placed, by following these steps:
- Find where it says
// code from step 3 will go here
in your code. - Copy and paste the code snippet below and replace the comment line.
const geojson = {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [-77.032, 38.913]
},
properties: {
title: 'Mapbox',
description: 'Washington, D.C.'
}
},
{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [-122.414, 37.776]
},
properties: {
title: 'Mapbox',
description: 'San Francisco, California'
}
}
]
};
If you have a lot of GeoJSON data, you may want to load it as an external file rather than adding it inline. You can do so by linking to its URL, if it's hosted remotely, or by using fetch to load locally or from a third-party API.
Step 4: Add default markers to the map
Let's create and attach a marker at each point in our GeoJSON data. We'll start by using the default marker and customize our markers in Step 5.
To do so follow these steps:
- To add in your markers, copy and paste the following code and replace where it says
//code from step 4 will go here
.- This is located within your
script
, after the end of yourMap
object instantiation and before the</script>
tag.
- This is located within your
- Save your
index.html
file and refresh your browser to view your two default markers on the east and west coasts of the map.
// add markers to map
for (const feature of geojson.features) {
// code from step 5-1 will go here
// make a marker for each feature and add to the map
new mapboxgl.Marker().setLngLat(feature.geometry.coordinates).addTo(map); // Replace this line with code from step 5-2
//code from step 6 will go here
}
Your default markers should appear like they do in the image below:
Step 5: Customize and style your markers
Now that we've spawned two default markers, we can add custom HTML elements to control their appearances.
Step 5-1: Create an empty div for each point.
Let's make an HTML DOM element for each Marker
by passing an empty div
into the marker's constructor. This will attach each div
to a location listed in your GeoJSON data.
Add this code segment where it says // code from step 5-1 will go here
.
// create a HTML element for each feature
const el = document.createElement('div');
el.className = 'marker';
Step 5-2: Pass the empty div into the marker's constructor.
Next replace the code on the line that ends with // Replace this line with code from step 5-2
with the following segment of code:
new mapboxgl.Marker(el).setLngLat(feature.geometry.coordinates).addTo(map);
This will pass the empty div
(stored in the variable el
) into the constructor.
Step 5-3: Add CSS to style the markers.
You'll need to specify the style of the marker, so the div
renders something at each point. This will add an image to each of the markers and adjust them to a uniform size of 50 by 50 pixels and change the image of the cursor when it's over the element so your users know they can interact with it.
To do this, copy and paste the CSS code below in the style section of the header, where it says <!--code from step 5-3 will go here!-->
.
.marker {
background-image: url('https://docs.mapbox.com/demos/custom-markers-gl-js/mapbox-icon.png');
background-size: cover;
width: 50px;
height: 50px;
border-radius: 50%;
cursor: pointer;
}
Step 6: Attach popups to markers
Let's add the JavaScript needed to add the popups. These will contain information about each point and display the popup when a marker is clicked:
- Copy and paste the right above the end
</script>
tag, where it says//code from step 6 will go here
.- In this example, we're displaying the
title
anddescription
properties from the GeoJSON data, but you are able to customize what data is stored and shown as you see fit.
- In this example, we're displaying the
- Save your file and refresh your browser.
- Click on the markers and to view the popups displays.
new mapboxgl.Marker(el)
.setLngLat(feature.geometry.coordinates)
.setPopup(
new mapboxgl.Popup({ offset: 25 }) // add popups
.setHTML(
`<h3>${feature.properties.title}</h3><p>${feature.properties.description}</p>`
)
)
.addTo(map);
Notice that you've added an offset
value when you declare popups using the mapboxgl.Popup
method. This makes sure your popups are positioned near your markers and not directly on top of them.
Step 7: Add a style for marker using CSS
Now lastly, let's style our popups to make them present more neatly, by completing the following:
Copy and paste the CSS
code below and paste the code inside your style
tag below the .marker
declaration on line 38, where it says <!--code from step 7 will go here!-->
.
.mapboxgl-popup {
max-width: 200px;
}
.mapboxgl-popup-content {
text-align: center;
font-family: 'Open Sans', sans-serif;
}
Finished Product
You've made an interactive marker map with custom data and styling using Mapbox GL JS.
Finished Interactive Map
Finished Code Snippet
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Demo: Add custom markers in Mapbox GL JS</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link
href="https://fonts.googleapis.com/css?family=Open+Sans"
rel="stylesheet"
/>
<script src="https://api.tiles.mapbox.com/mapbox-gl-js/v3.3.0/mapbox-gl.js"></script>
<link
href="https://api.tiles.mapbox.com/mapbox-gl-js/v3.3.0/mapbox-gl.css"
rel="stylesheet"
/>
<style>
body {
margin: 0;
padding: 0;
}
#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
.marker {
background-image: url('https://docs.mapbox.com/demos/custom-markers-gl-js/mapbox-icon.png');
background-size: cover;
width: 50px;
height: 50px;
border-radius: 50%;
cursor: pointer;
}
.mapboxgl-popup {
max-width: 200px;
}
.mapboxgl-popup-content {
text-align: center;
font-family: 'Open Sans', sans-serif;
}
</style>
</head>
<body>
<div id="map"></div>
<script>
mapboxgl.accessToken = '{{MAPBOX_ACCESS_TOKEN}}';
const geojson = {
'type': 'FeatureCollection',
'features': [
{
'type': 'Feature',
'geometry': {
'type': 'Point',
'coordinates': [-77.032, 38.913]
},
'properties': {
'title': 'Mapbox',
'description': 'Washington, D.C.'
}
},
{
'type': 'Feature',
'geometry': {
'type': 'Point',
'coordinates': [-122.414, 37.776]
},
'properties': {
'title': 'Mapbox',
'description': 'San Francisco, California'
}
}
]
};
const map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/light-v11',
center: [-96, 37.8],
zoom: 3
});
// add markers to map
for (const feature of geojson.features) {
// create a HTML element for each feature
const el = document.createElement('div');
el.className = 'marker';
// make a marker for each feature and add it to the map
new mapboxgl.Marker(el)
.setLngLat(feature.geometry.coordinates)
.setPopup(
new mapboxgl.Popup({ offset: 25 }) // add popups
.setHTML(
`<h3>${feature.properties.title}</h3><p>${feature.properties.description}</p>`
)
)
.addTo(map);
}
</script>
</body>
</html>
Next steps
Now that you've created a project using Mapbox GL JS, we recommend checking out our other tutorials to extend your web app:
- Add points to a map using Mapbox Studio and Mapbox GL JS.
- Build a store locator using Mapbox GL JS.
- Show changes over time with Mapbox GL JS.
- Analyze data with Turf.js and Mapbox GL JS.
Explore our Mapbox GL JS examples for more ideas on how to extend your project and code to get you started.