> For the complete documentation index, see [llms.txt](https://docs.mapbox.com/mapbox-gl-js/ja/llms.txt)

# Add interactions to a Mapbox Standard Style

This example demonstrates how to use [`addInteraction`](https://docs.mapbox.com/mapbox-gl-js/ja/api/map/#map#addinteraction) with Mapbox Standard Style's built-in [Featuresets](https://docs.mapbox.com/map-styles/standard/api/#featuresets) and [configuration properties](https://docs.mapbox.com/map-styles/standard/api/#configuration-properties). The code below demonstrates how to:

-   Highlight place labels on hover using the `highlight` feature state and `colorPlaceLabelHighlight` configuration property
-   Select place labels on click using the `select` feature state and `colorPlaceLabelSelect` configuration property

> Example code:

**JavaScript**

```html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Add interactions to a Mapbox Standard Style</title>
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
<link href="https://api.mapbox.com/mapbox-gl-js/v3.29.0/mapbox-gl.css" rel="stylesheet">
<script src="https://api.mapbox.com/mapbox-gl-js/v3.29.0/mapbox-gl.js"></script>
<style>
body { margin: 0; padding: 0; }
#map { position: absolute; top: 0; bottom: 0; width: 100%; }
</style>
</head>
<body>
<style>
    .map-overlay {
        position: absolute;
        right: 0;
        top: 0;
        width: 230px;
        padding: 10px;
        color: #1a2224;
        font: 12px/20px sans-serif;
        display: none;
    }

    .map-overlay-inner {
        background: #fff;
        padding: 10px;
        border-radius: 3px;
    }
</style>

<div id="map"></div>
<div class="map-overlay" id="properties"></div>

<script>
    const map = new mapboxgl.Map({
        // TO MAKE THE MAP APPEAR YOU MUST
        // ADD YOUR ACCESS TOKEN FROM
        // https://account.mapbox.com
        accessToken: 'YOUR_MAPBOX_ACCESS_TOKEN',
        container: 'map',
        center: [-74, 40.72],
        zoom: 12,
        bearing: 30,
        style: 'mapbox://styles/mapbox/standard',
        config: {
            // Mapbox Standard offers a set of configuration properties that can be used to change the appearance of the basemap.
            // The configuration can be updated in runtime using `setConfigProperty` or by providing the `config` object during map initialization.
            // See the full list of available properties in the Mapbox Standard style documentation: https://docs.mapbox.com/mapbox-gl-js/guides/styles/#mapbox-standard-1
            'basemap': {
                'colorPlaceLabelHighlight': 'red',
                'colorPlaceLabelSelect': 'blue'
            }
        }
    });

    let selectedPlace;
    let hoveredPlace;

    const card = document.getElementById('properties');
    const showCard = (feature) => {
        const state = Object.entries(map.getFeatureState(feature))
            .map(([key, value]) => `<li><b>${key}</b>: ${value}</li>`)
            .join('');

        const properties = Object.entries(feature.properties)
            .map(([key, value]) => `<li><b>${key}</b>: ${value}</li>`)
            .join('');

        card.innerHTML = `
                <div class="map-overlay-inner">
                    <b>featureset</b>: <code>${feature.target.featuresetId}</code><br>
                    <b>feature state</b>: <code>${state}</code>
                    <hr><b>Properties</b>
                    ${properties}
                </div>`;

        card.style.display = 'block';
    };

    // Place Click Interaction:
    // Uses 'select' feature state to persistently highlight selected place
    // Selected color controlled by `colorPlaceLabelSelect` configuration property
    map.addInteraction('place-click', {
        type: 'click',
        target: { featuresetId: 'place-labels', importId: 'basemap' },
        handler: ({ feature }) => {
            if (selectedPlace) {
                map.setFeatureState(selectedPlace, { select: false });
            }
            selectedPlace = feature;
            map.setFeatureState(feature, { select: true });
            showCard(feature);
        }
    });

    // Place Hover Interaction:
    // Uses `highlight` feature state for temporary hover effect
    // Highlight color controlled by `colorPlaceLabelHighlight` configuration property
    map.addInteraction('place-mouseenter', {
        type: 'mouseenter',
        target: { featuresetId: 'place-labels', importId: 'basemap' },
        handler: ({ feature }) => {
            if (hoveredPlace && hoveredPlace.id === feature.id) return;

            if (hoveredPlace) {
                map.setFeatureState(hoveredPlace, { highlight: false });
            }

            hoveredPlace = feature;
            map.setFeatureState(feature, { highlight: true });
            map.getCanvas().style.cursor = 'pointer';

            if (!selectedPlace) {
                showCard(feature);
            }
        }
    });

    // Place Hover Interaction:
    // Removes `highlight` feature state when mouse leaves place label
    map.addInteraction('place-mouseleave', {
        type: 'mouseleave',
        target: { featuresetId: 'place-labels', importId: 'basemap' },
        handler: () => {
            if (hoveredPlace) {
                map.setFeatureState(hoveredPlace, { highlight: false });
                hoveredPlace = null;
            }
            if (!selectedPlace) {
                card.style.display = 'none';
            }
            map.getCanvas().style.cursor = '';
            return false;
        }
    });

    // Map Click Interaction:
    // Clears 'select' feature state when clicking on map background
    map.addInteraction('map-click', {
        type: 'click',
        handler: () => {
            if (selectedPlace) {
                map.setFeatureState(selectedPlace, { select: false });
                selectedPlace = null;
            }
            card.style.display = 'none';
            return false;
        }
    });
</script>

</body>
</html>
```

**React**

```jsx
import React, { useState, useEffect, useRef } from 'react';
import * as mapboxgl from 'mapbox-gl/esm';

import 'mapbox-gl/dist/mapbox-gl.css';

const MapboxExample = () => {
  const mapContainerRef = useRef(null);
  const mapRef = useRef(null);

  // State
  const [selectedPlace, setSelectedPlace] = useState(null);
  const [hoveredPlace, setHoveredPlace] = useState(null);

  // Refs to track the latest state values
  const selectedPlaceRef = useRef(null);
  const hoveredPlaceRef = useRef(null);

  useEffect(() => {
    const map = (mapRef.current = new mapboxgl.Map({
      // TO MAKE THE MAP APPEAR YOU MUST
      // ADD YOUR ACCESS TOKEN FROM
      // https://account.mapbox.com
      accessToken: 'YOUR_MAPBOX_ACCESS_TOKEN',
      container: mapContainerRef.current,
      center: [-74, 40.72],
      zoom: 12,
      bearing: 30,
      style: 'mapbox://styles/mapbox/standard',
      config: {
        basemap: {
          colorPlaceLabelHighlight: 'red',
          colorPlaceLabelSelect: 'blue'
        }
      }
    }));

    map.addInteraction('place-click', {
      type: 'click',
      target: { featuresetId: 'place-labels', importId: 'basemap' },
      handler: ({ feature }) => {
        if (selectedPlaceRef.current) {
          map.setFeatureState(selectedPlaceRef.current, { select: false });
        }
        map.setFeatureState(feature, { select: true });
        setSelectedPlace(feature);
      }
    });

    map.addInteraction('place-mouseenter', {
      type: 'mouseenter',
      target: { featuresetId: 'place-labels', importId: 'basemap' },
      handler: ({ feature }) => {
        if (
          hoveredPlaceRef.current &&
          hoveredPlaceRef.current.id === feature.id
        )
          return;
        if (hoveredPlaceRef.current) {
          map.setFeatureState(hoveredPlaceRef.current, { highlight: false });
        }
        map.getCanvas().style.cursor = 'pointer';
        map.setFeatureState(feature, { highlight: true });
        setHoveredPlace(feature);
      }
    });

    map.addInteraction('place-mouseleave', {
      type: 'mouseleave',
      target: { featuresetId: 'place-labels', importId: 'basemap' },
      handler: () => {
        if (hoveredPlaceRef.current) {
          map.setFeatureState(hoveredPlaceRef.current, { highlight: false });
          setHoveredPlace(null);
        }
        map.getCanvas().style.cursor = '';
      }
    });

    map.addInteraction('map-click', {
      type: 'click',
      handler: () => {
        if (selectedPlaceRef.current) {
          map.setFeatureState(selectedPlaceRef.current, { select: false });
          setSelectedPlace(null);
        }
      }
    });

    return () => map.remove();
  }, []);

  // Sync Refs with State
  useEffect(() => {
    selectedPlaceRef.current = selectedPlace;
  }, [selectedPlace]);

  useEffect(() => {
    hoveredPlaceRef.current = hoveredPlace;
  }, [hoveredPlace]);

  const displayFeature = selectedPlace || hoveredPlace;
  return (
    <div style={{ position: 'relative', width: '100%', height: '100vh' }}>
      <div ref={mapContainerRef} style={{ width: '100%', height: '100%' }} />
      <div
        className="map-overlay"
        style={{
          position: 'absolute',
          right: 0,
          top: 0,
          width: '230px',
          padding: '10px',
          color: '#1a2224',
          fontSize: '12px',
          lineHeight: '20px',
          fontFamily: 'sans-serif'
        }}
      >
        {displayFeature && (
          <div
            className="map-overlay-inner"
            style={{
              background: '#fff',
              padding: '10px',
              borderRadius: '3px'
            }}
          >
            <b>featureset</b>: <code>{displayFeature.target.featuresetId}</code>
            <br />
            <b>feature state</b>:{' '}
            <code>
              {Object.entries(
                mapRef.current.getFeatureState(displayFeature)
              ).map(([key, value]) => (
                <li>
                  <b>{key}</b>: {value.toString()}
                </li>
              ))}
            </code>
            <hr />
            <b>properties</b>
            {Object.entries(displayFeature.properties).map(([key, value]) => (
              <li>
                <b>{key}</b>: {value.toString()}
              </li>
            ))}
          </div>
        )}
      </div>
    </div>
  );
};

export default MapboxExample;
```