Display a pop-up

Learn how to display feature attributes in a pop-up.

A pop-up, also known as a "popup", is a visual element that displays information about a feature when it is clicked. You typically style and configure a pop-up using HTML and CSS for each layer in a map. Pop-ups can display attribute values, calculated values, or rich content such as images, charts, or videos.

In this tutorial, you create an interactive pop-up for the Trailheads feature layer in the Santa Monica Mountains. When a feature is clicked, a pop-up is displayed containing the name of the trail and the service that manages it.

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. To get started, either complete the Display a map tutorial or .

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 load handler

You need to wait for the map to be completely loaded before adding any layers

  1. Add an event handler to the map load event.

    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" />
        <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" />
        <style>
          html,
          body,
          #map {
            padding: 0;
            margin: 0;
            height: 100%;
            width: 100%;
            font-family: Arial, Helvetica, sans-serif;
            font-size: 14px;
            color: #323232;
          }
        </style>
      </head>
      <body>
        <div id="map"></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]
          });
    
          map.once("load", () => {
    
            map.addSource("trailheads", {
              type: "vector",
              tiles: ["https://vectortileservices3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Trailheads/VectorTileServer/tile/{z}/{y}/{x}.pbf"]
            });
    
            map.addLayer({
              id: "trailheads-circle",
              type: "circle",
              source: "trailheads",
              "source-layer": "Trailheads",
    
              paint: {
                "circle-color": "hsla(200,80%,70%,0.5)",
                "circle-stroke-width": 2,
                "circle-radius": 5,
                "circle-stroke-color": "hsl(200,80%,50%)"
              }
            });
    
            map.on("click", "trailheads-circle", (e) => {
              const trailhead = e.features[0];
    
              new mapboxgl.Popup()
    
                .setHTML(`<b>${trailhead.properties.TRL_NAME}</b>${trailhead.properties.PARK_NAME}`)
    
                .setLngLat(trailhead.geometry.coordinates)
                .addTo(map);
    
            });
    
            map.on("mouseenter", "trailheads-circle", () => {
              map.getCanvas().style.cursor = "pointer";
            });
    
            map.on("mouseleave", "trailheads-circle", () => {
              map.getCanvas().style.cursor = "";
            });
    
          });
    
        </script>
    
      </body>
    </html>

Add the trailheads layer

You will use a vector tile source and a circle layer to display the trailheads.

  1. Inside the load handler, add a source called trailheads and set the url property of the vector tile 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" />
        <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" />
        <style>
          html,
          body,
          #map {
            padding: 0;
            margin: 0;
            height: 100%;
            width: 100%;
            font-family: Arial, Helvetica, sans-serif;
            font-size: 14px;
            color: #323232;
          }
        </style>
      </head>
      <body>
        <div id="map"></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]
          });
    
          map.once("load", () => {
    
            map.addSource("trailheads", {
              type: "vector",
              tiles: ["https://vectortileservices3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Trailheads/VectorTileServer/tile/{z}/{y}/{x}.pbf"]
            });
    
            map.addLayer({
              id: "trailheads-circle",
              type: "circle",
              source: "trailheads",
              "source-layer": "Trailheads",
    
              paint: {
                "circle-color": "hsla(200,80%,70%,0.5)",
                "circle-stroke-width": 2,
                "circle-radius": 5,
                "circle-stroke-color": "hsl(200,80%,50%)"
              }
            });
    
            map.on("click", "trailheads-circle", (e) => {
              const trailhead = e.features[0];
    
              new mapboxgl.Popup()
    
                .setHTML(`<b>${trailhead.properties.TRL_NAME}</b>${trailhead.properties.PARK_NAME}`)
    
                .setLngLat(trailhead.geometry.coordinates)
                .addTo(map);
    
            });
    
            map.on("mouseenter", "trailheads-circle", () => {
              map.getCanvas().style.cursor = "pointer";
            });
    
            map.on("mouseleave", "trailheads-circle", () => {
              map.getCanvas().style.cursor = "";
            });
    
          });
    
        </script>
    
      </body>
    </html>
  2. Add a circle layer called trailheads-circle, which references the trailheads source.

    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" />
        <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" />
        <style>
          html,
          body,
          #map {
            padding: 0;
            margin: 0;
            height: 100%;
            width: 100%;
            font-family: Arial, Helvetica, sans-serif;
            font-size: 14px;
            color: #323232;
          }
        </style>
      </head>
      <body>
        <div id="map"></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]
          });
    
          map.once("load", () => {
    
            map.addSource("trailheads", {
              type: "vector",
              tiles: ["https://vectortileservices3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Trailheads/VectorTileServer/tile/{z}/{y}/{x}.pbf"]
            });
    
            map.addLayer({
              id: "trailheads-circle",
              type: "circle",
              source: "trailheads",
              "source-layer": "Trailheads",
    
              paint: {
                "circle-color": "hsla(200,80%,70%,0.5)",
                "circle-stroke-width": 2,
                "circle-radius": 5,
                "circle-stroke-color": "hsl(200,80%,50%)"
              }
            });
    
            map.on("click", "trailheads-circle", (e) => {
              const trailhead = e.features[0];
    
              new mapboxgl.Popup()
    
                .setHTML(`<b>${trailhead.properties.TRL_NAME}</b>${trailhead.properties.PARK_NAME}`)
    
                .setLngLat(trailhead.geometry.coordinates)
                .addTo(map);
    
            });
    
            map.on("mouseenter", "trailheads-circle", () => {
              map.getCanvas().style.cursor = "pointer";
            });
    
            map.on("mouseleave", "trailheads-circle", () => {
              map.getCanvas().style.cursor = "";
            });
    
          });
    
        </script>
    
      </body>
    </html>

Add a click handler

To display a pop-up appear when a trailheads feature is clicked, add a click event handler. This handler is called with the features under the pointer where you clicked.

  1. Add a handler for theclick event on the Map. Pass the trailheads-circle id to the on method so the handler is only called when you click on that layer. Inside, store the first element of the features property to a trailhead variable.

    If there are multiple overlapping features where you click, all of those features will be included in the features array. The first element listed will be the topmost feature.

    See the Mapbox GL JS documentation for more map events you can respond to.

    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" />
        <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" />
        <style>
          html,
          body,
          #map {
            padding: 0;
            margin: 0;
            height: 100%;
            width: 100%;
            font-family: Arial, Helvetica, sans-serif;
            font-size: 14px;
            color: #323232;
          }
        </style>
      </head>
      <body>
        <div id="map"></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]
          });
    
          map.once("load", () => {
    
            map.addSource("trailheads", {
              type: "vector",
              tiles: ["https://vectortileservices3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Trailheads/VectorTileServer/tile/{z}/{y}/{x}.pbf"]
            });
    
            map.addLayer({
              id: "trailheads-circle",
              type: "circle",
              source: "trailheads",
              "source-layer": "Trailheads",
    
              paint: {
                "circle-color": "hsla(200,80%,70%,0.5)",
                "circle-stroke-width": 2,
                "circle-radius": 5,
                "circle-stroke-color": "hsl(200,80%,50%)"
              }
            });
    
            map.on("click", "trailheads-circle", (e) => {
              const trailhead = e.features[0];
    
              new mapboxgl.Popup()
    
                .setHTML(`<b>${trailhead.properties.TRL_NAME}</b>${trailhead.properties.PARK_NAME}`)
    
                .setLngLat(trailhead.geometry.coordinates)
                .addTo(map);
    
            });
    
            map.on("mouseenter", "trailheads-circle", () => {
              map.getCanvas().style.cursor = "pointer";
            });
    
            map.on("mouseleave", "trailheads-circle", () => {
              map.getCanvas().style.cursor = "";
            });
    
          });
    
        </script>
    
      </body>
    </html>

Create the pop-up

You create a new Popup with mapboxgl.Popup. The default parameters give a simple white bubble which stays open until you click its close button or somewhere on the map.

To add content, you use Popup.setHTML. Use your trailhead variable to make the HTML string. It is a GeoJSON object, so the clicked trailhead's attributes are in a properties object. The name of the trail is stored in TRL_NAME and the name of the park service is in PARK_NAME.

  1. Create a new Popup.

    You can pass additional options, to change behavior such as whether there is a close button in the corner. See the Mapbox documentation for more details.

    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" />
        <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" />
        <style>
          html,
          body,
          #map {
            padding: 0;
            margin: 0;
            height: 100%;
            width: 100%;
            font-family: Arial, Helvetica, sans-serif;
            font-size: 14px;
            color: #323232;
          }
        </style>
      </head>
      <body>
        <div id="map"></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]
          });
    
          map.once("load", () => {
    
            map.addSource("trailheads", {
              type: "vector",
              tiles: ["https://vectortileservices3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Trailheads/VectorTileServer/tile/{z}/{y}/{x}.pbf"]
            });
    
            map.addLayer({
              id: "trailheads-circle",
              type: "circle",
              source: "trailheads",
              "source-layer": "Trailheads",
    
              paint: {
                "circle-color": "hsla(200,80%,70%,0.5)",
                "circle-stroke-width": 2,
                "circle-radius": 5,
                "circle-stroke-color": "hsl(200,80%,50%)"
              }
            });
    
            map.on("click", "trailheads-circle", (e) => {
              const trailhead = e.features[0];
    
              new mapboxgl.Popup()
    
                .setHTML(`<b>${trailhead.properties.TRL_NAME}</b>${trailhead.properties.PARK_NAME}`)
    
                .setLngLat(trailhead.geometry.coordinates)
                .addTo(map);
    
            });
    
            map.on("mouseenter", "trailheads-circle", () => {
              map.getCanvas().style.cursor = "pointer";
            });
    
            map.on("mouseleave", "trailheads-circle", () => {
              map.getCanvas().style.cursor = "";
            });
    
          });
    
        </script>
    
      </body>
    </html>
  2. Use Popup.setHTML to set the contents: the name of the trail in an <h3> tag, then the name of the park service.

    Add line.
                                                                                     
    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
        <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" />
        <style>
          html,
          body,
          #map {
            padding: 0;
            margin: 0;
            height: 100%;
            width: 100%;
            font-family: Arial, Helvetica, sans-serif;
            font-size: 14px;
            color: #323232;
          }
        </style>
      </head>
      <body>
        <div id="map"></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]
          });
    
          map.once("load", () => {
    
            map.addSource("trailheads", {
              type: "vector",
              tiles: ["https://vectortileservices3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Trailheads/VectorTileServer/tile/{z}/{y}/{x}.pbf"]
            });
    
            map.addLayer({
              id: "trailheads-circle",
              type: "circle",
              source: "trailheads",
              "source-layer": "Trailheads",
    
              paint: {
                "circle-color": "hsla(200,80%,70%,0.5)",
                "circle-stroke-width": 2,
                "circle-radius": 5,
                "circle-stroke-color": "hsl(200,80%,50%)"
              }
            });
    
            map.on("click", "trailheads-circle", (e) => {
              const trailhead = e.features[0];
    
              new mapboxgl.Popup()
    
                .setHTML(`<b>${trailhead.properties.TRL_NAME}</b>${trailhead.properties.PARK_NAME}`)
    
                .setLngLat(trailhead.geometry.coordinates)
                .addTo(map);
    
            });
    
            map.on("mouseenter", "trailheads-circle", () => {
              map.getCanvas().style.cursor = "pointer";
            });
    
            map.on("mouseleave", "trailheads-circle", () => {
              map.getCanvas().style.cursor = "";
            });
    
          });
    
        </script>
    
      </body>
    </html>

Add the pop-up to the map

When you create the Popup, it is not immediately added to the map. You need to call setLngLat to provide the position, then addTo to attach it to the Map.

  1. Set the location of the Popup to the location of the feature clicked on by using the setLngLat method, then add it to the map.

    Most methods of Popup return the Popup itself. This means you can chain method calls, using each output to call the next.

    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" />
        <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" />
        <style>
          html,
          body,
          #map {
            padding: 0;
            margin: 0;
            height: 100%;
            width: 100%;
            font-family: Arial, Helvetica, sans-serif;
            font-size: 14px;
            color: #323232;
          }
        </style>
      </head>
      <body>
        <div id="map"></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]
          });
    
          map.once("load", () => {
    
            map.addSource("trailheads", {
              type: "vector",
              tiles: ["https://vectortileservices3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Trailheads/VectorTileServer/tile/{z}/{y}/{x}.pbf"]
            });
    
            map.addLayer({
              id: "trailheads-circle",
              type: "circle",
              source: "trailheads",
              "source-layer": "Trailheads",
    
              paint: {
                "circle-color": "hsla(200,80%,70%,0.5)",
                "circle-stroke-width": 2,
                "circle-radius": 5,
                "circle-stroke-color": "hsl(200,80%,50%)"
              }
            });
    
            map.on("click", "trailheads-circle", (e) => {
              const trailhead = e.features[0];
    
              new mapboxgl.Popup()
    
                .setHTML(`<b>${trailhead.properties.TRL_NAME}</b>${trailhead.properties.PARK_NAME}`)
    
                .setLngLat(trailhead.geometry.coordinates)
                .addTo(map);
    
            });
    
            map.on("mouseenter", "trailheads-circle", () => {
              map.getCanvas().style.cursor = "pointer";
            });
    
            map.on("mouseleave", "trailheads-circle", () => {
              map.getCanvas().style.cursor = "";
            });
    
          });
    
        </script>
    
      </body>
    </html>

Change the cursor on hover

To indicate that you can interact with a layer by clicking, it is useful to change the mouse cursor to a pointing hand when hovering over the layer. You use Map.getCanvas to access the map's <canvas> element, so you can set the CSS cursor property.

  1. Add a handler to the mouseenter event, changing the cursor to a pointer.

    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" />
        <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" />
        <style>
          html,
          body,
          #map {
            padding: 0;
            margin: 0;
            height: 100%;
            width: 100%;
            font-family: Arial, Helvetica, sans-serif;
            font-size: 14px;
            color: #323232;
          }
        </style>
      </head>
      <body>
        <div id="map"></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]
          });
    
          map.once("load", () => {
    
            map.addSource("trailheads", {
              type: "vector",
              tiles: ["https://vectortileservices3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Trailheads/VectorTileServer/tile/{z}/{y}/{x}.pbf"]
            });
    
            map.addLayer({
              id: "trailheads-circle",
              type: "circle",
              source: "trailheads",
              "source-layer": "Trailheads",
    
              paint: {
                "circle-color": "hsla(200,80%,70%,0.5)",
                "circle-stroke-width": 2,
                "circle-radius": 5,
                "circle-stroke-color": "hsl(200,80%,50%)"
              }
            });
    
            map.on("click", "trailheads-circle", (e) => {
              const trailhead = e.features[0];
    
              new mapboxgl.Popup()
    
                .setHTML(`<b>${trailhead.properties.TRL_NAME}</b>${trailhead.properties.PARK_NAME}`)
    
                .setLngLat(trailhead.geometry.coordinates)
                .addTo(map);
    
            });
    
            map.on("mouseenter", "trailheads-circle", () => {
              map.getCanvas().style.cursor = "pointer";
            });
    
            map.on("mouseleave", "trailheads-circle", () => {
              map.getCanvas().style.cursor = "";
            });
    
          });
    
        </script>
    
      </body>
    </html>
  2. Add a handler to the mouseleave event, changing the cursor back to the default.

    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" />
        <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" />
        <style>
          html,
          body,
          #map {
            padding: 0;
            margin: 0;
            height: 100%;
            width: 100%;
            font-family: Arial, Helvetica, sans-serif;
            font-size: 14px;
            color: #323232;
          }
        </style>
      </head>
      <body>
        <div id="map"></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]
          });
    
          map.once("load", () => {
    
            map.addSource("trailheads", {
              type: "vector",
              tiles: ["https://vectortileservices3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Trailheads/VectorTileServer/tile/{z}/{y}/{x}.pbf"]
            });
    
            map.addLayer({
              id: "trailheads-circle",
              type: "circle",
              source: "trailheads",
              "source-layer": "Trailheads",
    
              paint: {
                "circle-color": "hsla(200,80%,70%,0.5)",
                "circle-stroke-width": 2,
                "circle-radius": 5,
                "circle-stroke-color": "hsl(200,80%,50%)"
              }
            });
    
            map.on("click", "trailheads-circle", (e) => {
              const trailhead = e.features[0];
    
              new mapboxgl.Popup()
    
                .setHTML(`<b>${trailhead.properties.TRL_NAME}</b>${trailhead.properties.PARK_NAME}`)
    
                .setLngLat(trailhead.geometry.coordinates)
                .addTo(map);
    
            });
    
            map.on("mouseenter", "trailheads-circle", () => {
              map.getCanvas().style.cursor = "pointer";
            });
    
            map.on("mouseleave", "trailheads-circle", () => {
              map.getCanvas().style.cursor = "";
            });
    
          });
    
        </script>
    
      </body>
    </html>

Run the app

In CodePen, run your code to display the map.

The map view should display the Trailheads feature layer. When you hover over a feature the cursor should change. When you click a feature, the name of the trailhead and its park name is displayed in a pop-up.

What's next?