Change the basemap layer

Learn how to change a basemap layer from the basemap layer service using Mapbox GL JS.

The basemap layer service provides a number of basemap layer styles such as topography, streets, and imagery that you can use in maps.

In this tutorial, you use a <select> dropdown menu to toggle between a number of different basemap layer styles.

Prerequisites

You need a free ArcGIS developer account to access your dashboard and API keys. The API key must be scoped to access the services used in this tutorial.

Steps

Create a new pen

  1. Go to CodePen to create a new pen for your application.

Set the API key

To access ArcGIS location services, you need an API key.

  1. Go to your dashboard to get an API key.

  2. In CodePen, update apiKey to use your key.

    Change line
              
    //
    
    const apiKey = "YOUR-API-KEY";
    const basemapEnum = "ArcGIS:Streets";
    const map = new mapboxgl.Map({
      container: "map", // the id of the div element
      style: `https://basemaps-api.arcgis.com/arcgis/rest/services/styles/${basemapEnum}?type=style&apiKey=${apiKey}`,
      zoom: 12, // starting zoom
      center: [-118.805, 34.027] // starting location [longitude, latitude]
    });
    

Add a selector

  1. Create a <div> tag to contain the <select> dropdown menu. Add a basemap layer enumeration for each <options></options> element.

    Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.
                                                                                                    
    
    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no" />
        <title>Mapbox GL JS Tutorials: Change the basemap layer</title>
    
        <style>
          html,
          body,
          #map {
            padding: 0;
            margin: 0;
            height: 100%;
            width: 100%;
            font-family: Arial, Helvetica, sans-serif;
            font-size: 14px;
            color: #323232;
          }
    
          #basemaps-wrapper {
            position: absolute;
            top: 20px;
            right: 20px;
            background: rgba(255, 255, 255, 0);
          }
          #basemaps {
            font-size: 16px;
            padding: 4px 8px;
          }
    
        </style>
        <script src="https://api.tiles.mapbox.com/mapbox-gl-js/v1.12.0/mapbox-gl.js"></script>
        <link href="https://api.tiles.mapbox.com/mapbox-gl-js/v1.12.0/mapbox-gl.css" rel="stylesheet" />
    
      </head>
    
      <body>
        <div id="map"></div>
    
        <div id="basemaps-wrapper">
    
          <select id="basemaps">
            <option value="ArcGIS:Streets">Streets</option>
            <option value="ArcGIS:Navigation">Navigation</option>
            <option value="ArcGIS:Topographic">Topographic</option>
            <option value="ArcGIS:LightGray">Light Gray</option>
            <option value="ArcGIS:DarkGray">Dark gray</option>
            <option value="ArcGIS:StreetsRelief">Streets Relief</option>
            <option value="ArcGIS:Imagery:Standard">Imagery</option>
            <option value="ArcGIS:ChartedTerritory">ChartedTerritory</option>
            <option value="ArcGIS:ColoredPencil">ColoredPencil</option>
            <option value="ArcGIS:Nova">Nova</option>
            <option value="ArcGIS:Midcentury">Midcentury</option>
            <option value="OSM:Standard">OSM</option>
            <option value="OSM:Streets">OSM:Streets</option>
          </select>
    
        </div>
    
        <script>
          const apiKey = "YOUR-API-KEY";
          const basemapEnum = "ArcGIS:Streets";
          const map = new mapboxgl.Map({
            container: "map", // the id of the div element
            style: `https://basemaps-api.arcgis.com/arcgis/rest/services/styles/${basemapEnum}?type=style&apiKey=${apiKey}`,
            zoom: 12, // starting zoom
            center: [-118.805, 34.027], // starting location [longitude, latitude]
            attributionControl: false
          }).addControl(
            new mapboxgl.AttributionControl({
              compact: true // reduces the copyright attributions view
            })
          );
    
          const baseUrl = "https://basemaps-api.arcgis.com/arcgis/rest/services/styles";
          const url = (name) => `${baseUrl}/${name}?type=style&apiKey=${apiKey}`;
    
          const setBasemap = (name) => {
            // Instantiate the given basemap layer.
            map.setStyle(url(name));
          };
    
          setBasemap("ArcGIS:Streets");
    
          const basemapsSelectElement = document.querySelector("#basemaps");
    
          basemapsSelectElement.addEventListener("change", (e) => {
            setBasemap(e.target.value);
          });
    
        </script>
    
      </body>
    </html>
  2. In the <style> element, add CSS stylings to the basemaps-wrapper and basemaps.

    Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.
                                                                                                    
    
    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no" />
        <title>Mapbox GL JS Tutorials: Change the basemap layer</title>
    
        <style>
          html,
          body,
          #map {
            padding: 0;
            margin: 0;
            height: 100%;
            width: 100%;
            font-family: Arial, Helvetica, sans-serif;
            font-size: 14px;
            color: #323232;
          }
    
          #basemaps-wrapper {
            position: absolute;
            top: 20px;
            right: 20px;
            background: rgba(255, 255, 255, 0);
          }
          #basemaps {
            font-size: 16px;
            padding: 4px 8px;
          }
    
        </style>
        <script src="https://api.tiles.mapbox.com/mapbox-gl-js/v1.12.0/mapbox-gl.js"></script>
        <link href="https://api.tiles.mapbox.com/mapbox-gl-js/v1.12.0/mapbox-gl.css" rel="stylesheet" />
    
      </head>
    
      <body>
        <div id="map"></div>
    
        <div id="basemaps-wrapper">
    
          <select id="basemaps">
            <option value="ArcGIS:Streets">Streets</option>
            <option value="ArcGIS:Navigation">Navigation</option>
            <option value="ArcGIS:Topographic">Topographic</option>
            <option value="ArcGIS:LightGray">Light Gray</option>
            <option value="ArcGIS:DarkGray">Dark gray</option>
            <option value="ArcGIS:StreetsRelief">Streets Relief</option>
            <option value="ArcGIS:Imagery:Standard">Imagery</option>
            <option value="ArcGIS:ChartedTerritory">ChartedTerritory</option>
            <option value="ArcGIS:ColoredPencil">ColoredPencil</option>
            <option value="ArcGIS:Nova">Nova</option>
            <option value="ArcGIS:Midcentury">Midcentury</option>
            <option value="OSM:Standard">OSM</option>
            <option value="OSM:Streets">OSM:Streets</option>
          </select>
    
        </div>
    
        <script>
          const apiKey = "YOUR-API-KEY";
          const basemapEnum = "ArcGIS:Streets";
          const map = new mapboxgl.Map({
            container: "map", // the id of the div element
            style: `https://basemaps-api.arcgis.com/arcgis/rest/services/styles/${basemapEnum}?type=style&apiKey=${apiKey}`,
            zoom: 12, // starting zoom
            center: [-118.805, 34.027], // starting location [longitude, latitude]
            attributionControl: false
          }).addControl(
            new mapboxgl.AttributionControl({
              compact: true // reduces the copyright attributions view
            })
          );
    
          const baseUrl = "https://basemaps-api.arcgis.com/arcgis/rest/services/styles";
          const url = (name) => `${baseUrl}/${name}?type=style&apiKey=${apiKey}`;
    
          const setBasemap = (name) => {
            // Instantiate the given basemap layer.
            map.setStyle(url(name));
          };
    
          setBasemap("ArcGIS:Streets");
    
          const basemapsSelectElement = document.querySelector("#basemaps");
    
          basemapsSelectElement.addEventListener("change", (e) => {
            setBasemap(e.target.value);
          });
    
        </script>
    
      </body>
    </html>

Set the basemap

Use a function to reference the basemap layer service and a style enumeration to update the map. This will be used when a selection is made.

  1. Create a baseUrl and a url element. The url element will append the name of the basemap selected from the dropdown menu.

    Add line.Add line.
                                                                                                    
    
    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no" />
        <title>Mapbox GL JS Tutorials: Change the basemap layer</title>
    
        <style>
          html,
          body,
          #map {
            padding: 0;
            margin: 0;
            height: 100%;
            width: 100%;
            font-family: Arial, Helvetica, sans-serif;
            font-size: 14px;
            color: #323232;
          }
    
          #basemaps-wrapper {
            position: absolute;
            top: 20px;
            right: 20px;
            background: rgba(255, 255, 255, 0);
          }
          #basemaps {
            font-size: 16px;
            padding: 4px 8px;
          }
    
        </style>
        <script src="https://api.tiles.mapbox.com/mapbox-gl-js/v1.12.0/mapbox-gl.js"></script>
        <link href="https://api.tiles.mapbox.com/mapbox-gl-js/v1.12.0/mapbox-gl.css" rel="stylesheet" />
    
      </head>
    
      <body>
        <div id="map"></div>
    
        <div id="basemaps-wrapper">
    
          <select id="basemaps">
            <option value="ArcGIS:Streets">Streets</option>
            <option value="ArcGIS:Navigation">Navigation</option>
            <option value="ArcGIS:Topographic">Topographic</option>
            <option value="ArcGIS:LightGray">Light Gray</option>
            <option value="ArcGIS:DarkGray">Dark gray</option>
            <option value="ArcGIS:StreetsRelief">Streets Relief</option>
            <option value="ArcGIS:Imagery:Standard">Imagery</option>
            <option value="ArcGIS:ChartedTerritory">ChartedTerritory</option>
            <option value="ArcGIS:ColoredPencil">ColoredPencil</option>
            <option value="ArcGIS:Nova">Nova</option>
            <option value="ArcGIS:Midcentury">Midcentury</option>
            <option value="OSM:Standard">OSM</option>
            <option value="OSM:Streets">OSM:Streets</option>
          </select>
    
        </div>
    
        <script>
          const apiKey = "YOUR-API-KEY";
          const basemapEnum = "ArcGIS:Streets";
          const map = new mapboxgl.Map({
            container: "map", // the id of the div element
            style: `https://basemaps-api.arcgis.com/arcgis/rest/services/styles/${basemapEnum}?type=style&apiKey=${apiKey}`,
            zoom: 12, // starting zoom
            center: [-118.805, 34.027], // starting location [longitude, latitude]
            attributionControl: false
          }).addControl(
            new mapboxgl.AttributionControl({
              compact: true // reduces the copyright attributions view
            })
          );
    
          const baseUrl = "https://basemaps-api.arcgis.com/arcgis/rest/services/styles";
          const url = (name) => `${baseUrl}/${name}?type=style&apiKey=${apiKey}`;
    
          const setBasemap = (name) => {
            // Instantiate the given basemap layer.
            map.setStyle(url(name));
          };
    
          setBasemap("ArcGIS:Streets");
    
          const basemapsSelectElement = document.querySelector("#basemaps");
    
          basemapsSelectElement.addEventListener("change", (e) => {
            setBasemap(e.target.value);
          });
    
        </script>
    
      </body>
    </html>
  2. Set the style of the map with the new basemap layer.

    Add line.Add line.Add line.Add line.
                                                                                                    
    
    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no" />
        <title>Mapbox GL JS Tutorials: Change the basemap layer</title>
    
        <style>
          html,
          body,
          #map {
            padding: 0;
            margin: 0;
            height: 100%;
            width: 100%;
            font-family: Arial, Helvetica, sans-serif;
            font-size: 14px;
            color: #323232;
          }
    
          #basemaps-wrapper {
            position: absolute;
            top: 20px;
            right: 20px;
            background: rgba(255, 255, 255, 0);
          }
          #basemaps {
            font-size: 16px;
            padding: 4px 8px;
          }
    
        </style>
        <script src="https://api.tiles.mapbox.com/mapbox-gl-js/v1.12.0/mapbox-gl.js"></script>
        <link href="https://api.tiles.mapbox.com/mapbox-gl-js/v1.12.0/mapbox-gl.css" rel="stylesheet" />
    
      </head>
    
      <body>
        <div id="map"></div>
    
        <div id="basemaps-wrapper">
    
          <select id="basemaps">
            <option value="ArcGIS:Streets">Streets</option>
            <option value="ArcGIS:Navigation">Navigation</option>
            <option value="ArcGIS:Topographic">Topographic</option>
            <option value="ArcGIS:LightGray">Light Gray</option>
            <option value="ArcGIS:DarkGray">Dark gray</option>
            <option value="ArcGIS:StreetsRelief">Streets Relief</option>
            <option value="ArcGIS:Imagery:Standard">Imagery</option>
            <option value="ArcGIS:ChartedTerritory">ChartedTerritory</option>
            <option value="ArcGIS:ColoredPencil">ColoredPencil</option>
            <option value="ArcGIS:Nova">Nova</option>
            <option value="ArcGIS:Midcentury">Midcentury</option>
            <option value="OSM:Standard">OSM</option>
            <option value="OSM:Streets">OSM:Streets</option>
          </select>
    
        </div>
    
        <script>
          const apiKey = "YOUR-API-KEY";
          const basemapEnum = "ArcGIS:Streets";
          const map = new mapboxgl.Map({
            container: "map", // the id of the div element
            style: `https://basemaps-api.arcgis.com/arcgis/rest/services/styles/${basemapEnum}?type=style&apiKey=${apiKey}`,
            zoom: 12, // starting zoom
            center: [-118.805, 34.027], // starting location [longitude, latitude]
            attributionControl: false
          }).addControl(
            new mapboxgl.AttributionControl({
              compact: true // reduces the copyright attributions view
            })
          );
    
          const baseUrl = "https://basemaps-api.arcgis.com/arcgis/rest/services/styles";
          const url = (name) => `${baseUrl}/${name}?type=style&apiKey=${apiKey}`;
    
          const setBasemap = (name) => {
            // Instantiate the given basemap layer.
            map.setStyle(url(name));
          };
    
          setBasemap("ArcGIS:Streets");
    
          const basemapsSelectElement = document.querySelector("#basemaps");
    
          basemapsSelectElement.addEventListener("change", (e) => {
            setBasemap(e.target.value);
          });
    
        </script>
    
      </body>
    </html>
  3. Run the code to ensure that the <select> element contains different basemap enumerations.

Add an event listener

Use an event listener to register a basemap change in the <select> element and to update the map.

  1. Set the default basemap to ArcGIS:Streets.

    Add line.
                                                                                                    
    
    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no" />
        <title>Mapbox GL JS Tutorials: Change the basemap layer</title>
    
        <style>
          html,
          body,
          #map {
            padding: 0;
            margin: 0;
            height: 100%;
            width: 100%;
            font-family: Arial, Helvetica, sans-serif;
            font-size: 14px;
            color: #323232;
          }
    
          #basemaps-wrapper {
            position: absolute;
            top: 20px;
            right: 20px;
            background: rgba(255, 255, 255, 0);
          }
          #basemaps {
            font-size: 16px;
            padding: 4px 8px;
          }
    
        </style>
        <script src="https://api.tiles.mapbox.com/mapbox-gl-js/v1.12.0/mapbox-gl.js"></script>
        <link href="https://api.tiles.mapbox.com/mapbox-gl-js/v1.12.0/mapbox-gl.css" rel="stylesheet" />
    
      </head>
    
      <body>
        <div id="map"></div>
    
        <div id="basemaps-wrapper">
    
          <select id="basemaps">
            <option value="ArcGIS:Streets">Streets</option>
            <option value="ArcGIS:Navigation">Navigation</option>
            <option value="ArcGIS:Topographic">Topographic</option>
            <option value="ArcGIS:LightGray">Light Gray</option>
            <option value="ArcGIS:DarkGray">Dark gray</option>
            <option value="ArcGIS:StreetsRelief">Streets Relief</option>
            <option value="ArcGIS:Imagery:Standard">Imagery</option>
            <option value="ArcGIS:ChartedTerritory">ChartedTerritory</option>
            <option value="ArcGIS:ColoredPencil">ColoredPencil</option>
            <option value="ArcGIS:Nova">Nova</option>
            <option value="ArcGIS:Midcentury">Midcentury</option>
            <option value="OSM:Standard">OSM</option>
            <option value="OSM:Streets">OSM:Streets</option>
          </select>
    
        </div>
    
        <script>
          const apiKey = "YOUR-API-KEY";
          const basemapEnum = "ArcGIS:Streets";
          const map = new mapboxgl.Map({
            container: "map", // the id of the div element
            style: `https://basemaps-api.arcgis.com/arcgis/rest/services/styles/${basemapEnum}?type=style&apiKey=${apiKey}`,
            zoom: 12, // starting zoom
            center: [-118.805, 34.027], // starting location [longitude, latitude]
            attributionControl: false
          }).addControl(
            new mapboxgl.AttributionControl({
              compact: true // reduces the copyright attributions view
            })
          );
    
          const baseUrl = "https://basemaps-api.arcgis.com/arcgis/rest/services/styles";
          const url = (name) => `${baseUrl}/${name}?type=style&apiKey=${apiKey}`;
    
          const setBasemap = (name) => {
            // Instantiate the given basemap layer.
            map.setStyle(url(name));
          };
    
          setBasemap("ArcGIS:Streets");
    
          const basemapsSelectElement = document.querySelector("#basemaps");
    
          basemapsSelectElement.addEventListener("change", (e) => {
            setBasemap(e.target.value);
          });
    
        </script>
    
      </body>
    </html>
  2. Create a basemapsSelectElement to return the basemap from the selector.

    Add line.
                                                                                                    
    
    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no" />
        <title>Mapbox GL JS Tutorials: Change the basemap layer</title>
    
        <style>
          html,
          body,
          #map {
            padding: 0;
            margin: 0;
            height: 100%;
            width: 100%;
            font-family: Arial, Helvetica, sans-serif;
            font-size: 14px;
            color: #323232;
          }
    
          #basemaps-wrapper {
            position: absolute;
            top: 20px;
            right: 20px;
            background: rgba(255, 255, 255, 0);
          }
          #basemaps {
            font-size: 16px;
            padding: 4px 8px;
          }
    
        </style>
        <script src="https://api.tiles.mapbox.com/mapbox-gl-js/v1.12.0/mapbox-gl.js"></script>
        <link href="https://api.tiles.mapbox.com/mapbox-gl-js/v1.12.0/mapbox-gl.css" rel="stylesheet" />
    
      </head>
    
      <body>
        <div id="map"></div>
    
        <div id="basemaps-wrapper">
    
          <select id="basemaps">
            <option value="ArcGIS:Streets">Streets</option>
            <option value="ArcGIS:Navigation">Navigation</option>
            <option value="ArcGIS:Topographic">Topographic</option>
            <option value="ArcGIS:LightGray">Light Gray</option>
            <option value="ArcGIS:DarkGray">Dark gray</option>
            <option value="ArcGIS:StreetsRelief">Streets Relief</option>
            <option value="ArcGIS:Imagery:Standard">Imagery</option>
            <option value="ArcGIS:ChartedTerritory">ChartedTerritory</option>
            <option value="ArcGIS:ColoredPencil">ColoredPencil</option>
            <option value="ArcGIS:Nova">Nova</option>
            <option value="ArcGIS:Midcentury">Midcentury</option>
            <option value="OSM:Standard">OSM</option>
            <option value="OSM:Streets">OSM:Streets</option>
          </select>
    
        </div>
    
        <script>
          const apiKey = "YOUR-API-KEY";
          const basemapEnum = "ArcGIS:Streets";
          const map = new mapboxgl.Map({
            container: "map", // the id of the div element
            style: `https://basemaps-api.arcgis.com/arcgis/rest/services/styles/${basemapEnum}?type=style&apiKey=${apiKey}`,
            zoom: 12, // starting zoom
            center: [-118.805, 34.027], // starting location [longitude, latitude]
            attributionControl: false
          }).addControl(
            new mapboxgl.AttributionControl({
              compact: true // reduces the copyright attributions view
            })
          );
    
          const baseUrl = "https://basemaps-api.arcgis.com/arcgis/rest/services/styles";
          const url = (name) => `${baseUrl}/${name}?type=style&apiKey=${apiKey}`;
    
          const setBasemap = (name) => {
            // Instantiate the given basemap layer.
            map.setStyle(url(name));
          };
    
          setBasemap("ArcGIS:Streets");
    
          const basemapsSelectElement = document.querySelector("#basemaps");
    
          basemapsSelectElement.addEventListener("change", (e) => {
            setBasemap(e.target.value);
          });
    
        </script>
    
      </body>
    </html>
  3. Add an event listener to update the map to the new basemap when the selector is changed.

    Add line.Add line.Add line.
                                                                                                    
    
    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no" />
        <title>Mapbox GL JS Tutorials: Change the basemap layer</title>
    
        <style>
          html,
          body,
          #map {
            padding: 0;
            margin: 0;
            height: 100%;
            width: 100%;
            font-family: Arial, Helvetica, sans-serif;
            font-size: 14px;
            color: #323232;
          }
    
          #basemaps-wrapper {
            position: absolute;
            top: 20px;
            right: 20px;
            background: rgba(255, 255, 255, 0);
          }
          #basemaps {
            font-size: 16px;
            padding: 4px 8px;
          }
    
        </style>
        <script src="https://api.tiles.mapbox.com/mapbox-gl-js/v1.12.0/mapbox-gl.js"></script>
        <link href="https://api.tiles.mapbox.com/mapbox-gl-js/v1.12.0/mapbox-gl.css" rel="stylesheet" />
    
      </head>
    
      <body>
        <div id="map"></div>
    
        <div id="basemaps-wrapper">
    
          <select id="basemaps">
            <option value="ArcGIS:Streets">Streets</option>
            <option value="ArcGIS:Navigation">Navigation</option>
            <option value="ArcGIS:Topographic">Topographic</option>
            <option value="ArcGIS:LightGray">Light Gray</option>
            <option value="ArcGIS:DarkGray">Dark gray</option>
            <option value="ArcGIS:StreetsRelief">Streets Relief</option>
            <option value="ArcGIS:Imagery:Standard">Imagery</option>
            <option value="ArcGIS:ChartedTerritory">ChartedTerritory</option>
            <option value="ArcGIS:ColoredPencil">ColoredPencil</option>
            <option value="ArcGIS:Nova">Nova</option>
            <option value="ArcGIS:Midcentury">Midcentury</option>
            <option value="OSM:Standard">OSM</option>
            <option value="OSM:Streets">OSM:Streets</option>
          </select>
    
        </div>
    
        <script>
          const apiKey = "YOUR-API-KEY";
          const basemapEnum = "ArcGIS:Streets";
          const map = new mapboxgl.Map({
            container: "map", // the id of the div element
            style: `https://basemaps-api.arcgis.com/arcgis/rest/services/styles/${basemapEnum}?type=style&apiKey=${apiKey}`,
            zoom: 12, // starting zoom
            center: [-118.805, 34.027], // starting location [longitude, latitude]
            attributionControl: false
          }).addControl(
            new mapboxgl.AttributionControl({
              compact: true // reduces the copyright attributions view
            })
          );
    
          const baseUrl = "https://basemaps-api.arcgis.com/arcgis/rest/services/styles";
          const url = (name) => `${baseUrl}/${name}?type=style&apiKey=${apiKey}`;
    
          const setBasemap = (name) => {
            // Instantiate the given basemap layer.
            map.setStyle(url(name));
          };
    
          setBasemap("ArcGIS:Streets");
    
          const basemapsSelectElement = document.querySelector("#basemaps");
    
          basemapsSelectElement.addEventListener("change", (e) => {
            setBasemap(e.target.value);
          });
    
        </script>
    
      </body>
    </html>

Run the app

In CodePen, run your code to display the map.

You should be able to use the select element to switch between basemap layers.

What's next?

Learn how to use additional ArcGIS location services in these tutorials: