Skip to main content

Add custom markers in Mapbox GL JS

Prerequisite

Familiarity with front-end development concepts.

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:

guide
Add markers

Learn more about how to use markers in Mapbox maps, including how to define what your markers look like, different ways to specify data sources, and how to choose the right approach to adding markers to your project.

chevron-right

Getting started

For this project, we recommend that you create a local folder called mapbox-markers to house your project files. You’ll see this folder referred to as your project folder.

To follow along with this guide you'll need:

  • An access token from your account. You will use an access token to associate a map with your account. Your access token is on the Account page.
  • A text editor. You'll be writing HTML, CSS, and JavaScript after all.
  • Custom image. This tutorial uses an image within each custom HTML marker to show two locations for the Mapbox offices in Washington, D.C. and San Francisco. You'll need to download the PNG file to use as your custom icon and save it in the same project folder as your index.html file.
arrow-downDownload PNG

Create a Mapbox GL JS map

Now you're ready to use Mapbox GL JS! To start, create a new HTML file and write code to initialize a Mapbox GL JS map.

Initialize your map

  1. Open your text editor.
  2. Create a new HTML file.
  3. Copy and paste the code below into your text editor to initialize your Mapbox GL JS map.
  1. Make sure you are using your API access token with mapboxgl.accessToken.
  2. Save your file as index.html in your project folder.
  3. Open the file in a browser.
  4. You should see an initialized Mapbox GL JS map displaying the Mapbox Light style in a browser window. You won't see your markers yet.
<!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.1.0/mapbox-gl.js'></script>
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v3.1.0/mapbox-gl.css' rel='stylesheet' />
<style>
body {
margin: 0;
padding: 0;
}

#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
</style>
</head>
<body>

<div id='map'></div>

<script>

mapboxgl.accessToken = ' <UserAccessToken /> ';

const map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/light-v11',
center: [-96, 37.8],
zoom: 3
});

// code from the next step will go here!

</script>

</body>
</html>

As you can see above, the Mapbox GL JS map requires several options:

  • container: the id of the <div> element on the page where the map should live. In this case, the id 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 URL mapbox://styles/mapbox/light-11.
  • center: the initial centerpoint of the map in [longitude, latitude] format.
  • zoom: the initial zoom level of the map.

Load GeoJSON data

Load your data by adding inline GeoJSON to your HTML file. This GeoJSON will be used to determine where your markers will appear on the map.

Copy and paste the following after the code that initializes your map but before the </script> tag. This code declares a constant geojson that stores the GeoJSON data.

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'
}
}
]
};
Note
If you have a large GeoJSON file, you may want to load it as an external source 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.

Add HTML markers

Now that you've loaded your data, add code to create an HTML DOM element for each marker and bind it to the GeoJSON features using the Mapbox GL JS Marker method. You'll be using the image you downloaded at the beginning of this tutorial, which should be saved in your project folder.

When you add a marker to a map using Marker, you are attaching an empty div to each point in your GeoJSON. You'll need to specify the style of the marker before adding it to the map.

Style markers

First, add the CSS you'll need to style your markers. In this case, add the image file you downloaded as the background-image for a class called marker. In your same index.html file, copy and paste the code inside your style tag below the #map declaration.

.marker {
background-image: url('mapbox-icon.png');
background-size: cover;
width: 50px;
height: 50px;
border-radius: 50%;
cursor: pointer;
}

Add markers to the map

Next, add the JavaScript needed to create the markers and add them to the map. Copy and paste the following code within your script tag after the end of your map object declaration but before the closing script tag.

// 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 to the map
new mapboxgl.Marker(el).setLngLat(feature.geometry.coordinates).addTo(map);
}

Save the file and refresh your browser. You should see you map displaying with your custom HTML markers.

These markers are added to the map as HTML elements, and they are styled using the CSS you wrote in the last step. This approach works well for cases in which you do not need to change the marker's style at runtime. If you want to add markers that can be styled dynamically (for example, changing sizes when a user zooms in or out), we suggest that you add your custom icons as markers using a symbol layer and style them using expressions. To learn more, see the Use Mapbox GL JS with a symbol layer section of our Add markers getting started guide.

Add popups

As your final step, add popups to your markers using Mapbox GL JS. You'll do this within the mapboxgl.Marker declaration.

Style popups

First, add the CSS code you'll need to style your popups. In the same index.html file, copy and paste the code inside your style tag below the .marker declaration.

.mapboxgl-popup {
max-width: 200px;
}

.mapboxgl-popup-content {
text-align: center;
font-family: 'Open Sans', sans-serif;
}

Attach popups to markers

Next, you'll add the JavaScript needed to add popups containing information about each point and display the popup when a marker is clicked:

  1. Copy and paste the .setPopup code below after the .setLngLat() method and before the .addTo() method within your script tags.
    • Make sure you're using the correct key for the data you want to display in your popups. In this example, you will be displaying your data's title and description properties.
  2. Save your file and refresh your browser.
  3. You should be able to click on the markers and see popups displayed.
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 to make sure your popups are centered over your markers.

Final product

You've made an interactive marker map with custom data and styling using Mapbox GL JS.

<!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.1.0/mapbox-gl.js"></script>
<link
href="https://api.tiles.mapbox.com/mapbox-gl-js/v3.1.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/help/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 = '<your access token here>';

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:

Explore our Mapbox GL JS examples for more ideas on how to extend your project and code to get you started.

Was this page helpful?