Display a popup

Learn how to display feature attributes in a popup.

Display a popup using API key authentication

A popup, 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 popup using HTML and CSS for each layer in a map. popups can display attribute values, calculated values, or rich content such as images, charts, or videos.

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

Prerequisites

Steps

Get the starter app

Select a type of authentication below and follow the steps to create a new application.

You can choose one of the following to create a new CodePen:

  • Option 1: Complete the Display a map tutorial; or,
  • Option 2: Start from the Display a map tutorial .

Set up authentication

Create developer credentials in your portal for the type of authentication you selected.

Create a new API key credential with the correct privileges to access the resources used in this tutorial.

  1. Go to the Create an API key tutorial and create an API key with the following privilege(s):
    • Privileges
      • Location services > Basemaps
    • Item access
      • Note: If you are using your own custom data layer for this tutorial, you need to grant the API key credentials access to the layer item. Learn more in Item access privileges.
  2. Copy the API key access token to your clipboard when prompted.

Set developer credentials

Use the API key or OAuth developer credentials so your application can access location services.

  1. Update the accessToken variable to use your API key.

    Expand
    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
        /* Use for API key authentication */
        const accessToken = "YOUR_ACCESS_TOKEN"
    
    Expand

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.

    Expand
    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
      <script>
        /* Use for API key authentication */
        const accessToken = "YOUR_ACCESS_TOKEN";
    
        // or
    
        /* Use for user authentication */
        // const session = await arcgisRest.ArcGISIdentityManager.beginOAuth2({
        //   clientId: "YOUR_CLIENT_ID", // Your client ID from OAuth credentials
        //   redirectUri: "YOUR_REDIRECT_URL", // The redirect URL registered in your OAuth credentials
        //   portal: "YOUR_PORTAL_URL" // Your portal URL
        // })
    
        // const accessToken = session.token;
        const basemapEnum = "arcgis/outdoor";
        const map = new maplibregl.Map({
          container: "map", // the id of the div element
          style: `https://basemapstyles-api.arcgis.com/arcgis/rest/services/styles/v2/styles/${basemapEnum}?token=${accessToken}`,
          zoom: 12, // starting zoom
          center: [-118.805, 34.027] // starting location [longitude, latitude]
        });
    
        map.once("load", () => {
    
        });
    
        // Add Esri attribution
        // Learn more in https://esriurl.com/attribution
        map._controls[0].options.customAttribution += " | Powered by Esri "
        map._controls[0]._updateAttributions()
    
      </script>
    
    Expand

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.

    Expand
    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
        map.once("load", () => {
    
          map.addSource("trailheads", {
            type: "vector",
            tiles: [
              "https://vectortileservices3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Trailheads/VectorTileServer/tile/{z}/{y}/{x}.pbf"
            ],
    
          });
    
        });
    
    Expand
  2. Add the data attribution for the vector tile source.

    • Go to the Trailheads (Santa Monica Mountains) item.
    • Scroll down to the Credits (Attribution) section and copy its value.
    • Create an attribution property and paste the attribution value from the item.
      Expand
      Use dark colors for code blocks
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      66
      67
      68
      69
      70
      71
      72
      73
      74
      75
      76
      77
      78
      79
      80
      81
      82
      83
      84
      85
      86
      87
      88
      89
      90
      91
      92
      93
      94
      95
      96
      97
      98
      99
      100
      101
      102
      103
      104
      105
      106
      107
          map.once("load", () => {
      
            map.addSource("trailheads", {
              type: "vector",
              tiles: [
                "https://vectortileservices3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Trailheads/VectorTileServer/tile/{z}/{y}/{x}.pbf"
              ],
      
              // Attribution text retrieved from https://arcgis.com/home/item.html?id=883cedb8c9fe4524b64d47666ed234a7
              attribution: "Los Angeles GeoHub"
      
            });
      
          });
      
      Expand
  3. Add a circle layer called trailheads-circle, which references the trailheads source.

    Expand
    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
        map.once("load", () => {
    
          map.addSource("trailheads", {
            type: "vector",
            tiles: [
              "https://vectortileservices3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Trailheads/VectorTileServer/tile/{z}/{y}/{x}.pbf"
            ],
    
            // Attribution text retrieved from https://arcgis.com/home/item.html?id=883cedb8c9fe4524b64d47666ed234a7
            attribution: "Los Angeles GeoHub"
    
          });
    
          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%)"
            }
          });
    
        });
    
    Expand

Add a click handler

To display a popup 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.

    Expand
    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
            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];
    
          });
    
    Expand

Create the popup

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.

    Expand
    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
          map.on("click", "trailheads-circle", (e) => {
            const trailhead = e.features[0];
    
            new maplibregl.Popup()
    
          });
    
    Expand
  2. Use Popup.setHTML to set the contents: the name of the trail in an <h3> tag, then the name of the park service.

    Expand
    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
            new maplibregl.Popup()
    
              .setHTML(`<b>${trailhead.properties.TRL_NAME}</b><br>${trailhead.properties.PARK_NAME}`)
    
    
    Expand

Add the popup 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.

    Expand
    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
            new maplibregl.Popup()
    
              .setHTML(`<b>${trailhead.properties.TRL_NAME}</b><br>${trailhead.properties.PARK_NAME}`)
    
              .setLngLat(trailhead.geometry.coordinates)
              .addTo(map);
    
    Expand

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.

    Expand
    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
          map.on("click", "trailheads-circle", (e) => {
            const trailhead = e.features[0];
    
            new maplibregl.Popup()
    
              .setHTML(`<b>${trailhead.properties.TRL_NAME}</b><br>${trailhead.properties.PARK_NAME}`)
    
              .setLngLat(trailhead.geometry.coordinates)
              .addTo(map);
    
          });
    
          map.on("mouseenter", "trailheads-circle", () => {
            map.getCanvas().style.cursor = "pointer";
          });
    
    
    Expand
  2. Add a handler to the mouseleave event, changing the cursor back to the default.

    Expand
    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
          map.on("mouseenter", "trailheads-circle", () => {
            map.getCanvas().style.cursor = "pointer";
          });
    
          map.on("mouseleave", "trailheads-circle", () => {
            map.getCanvas().style.cursor = "";
          });
    
    Expand

Run the app

Run the app.

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 popup.

What's next?

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

Your browser is no longer supported. Please upgrade your browser for the best experience. See our browser deprecation post for more details.