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

# Show and hide layers

This example adds a clickable interface that allows a user to enable and disable two different map layers.

The interface uses [`setLayoutProperty`](https://docs.mapbox.com/mapbox-gl-js/api/map/#map#setlayoutproperty) to toggle the value for each layer's [`visibility`](https://docs.mapbox.com/style-spec/reference/layers/) property between `visible` and `none`.

> Example code:

**JavaScript**

```html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Show and hide layers</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>
    #menu {
        background: #fff;
        position: absolute;
        z-index: 1;
        top: 10px;
        right: 10px;
        border-radius: 3px;
        width: 120px;
        border: 1px solid rgba(0, 0, 0, 0.4);
        font-family: 'Open Sans', sans-serif;
    }

    #menu a {
        font-size: 13px;
        color: #404040;
        display: block;
        margin: 0;
        padding: 0;
        padding: 10px;
        text-decoration: none;
        border-bottom: 1px solid rgba(0, 0, 0, 0.25);
        text-align: center;
    }

    #menu a:last-child {
        border: none;
    }

    #menu a:hover {
        background-color: #f8f8f8;
        color: #404040;
    }

    #menu a.active {
        background-color: #3887be;
        color: #ffffff;
    }

    #menu a.active:hover {
        background: #3074a4;
    }
</style>

<nav id="menu"></nav>
<div id="map"></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',
        // Choose from Mapbox's core styles, or make your own style with Mapbox Studio
        style: 'mapbox://styles/mapbox/standard',
        zoom: 15,
        center: [-71.97722138410576, -13.517379300798098]
    });

    // Wait until the map has finished loading.
    map.on('load', () => {
        // Add a custom vector tileset source. This tileset contains
        // point features representing museums. Each feature contains
        // three properties. For example:
        // {
        //     alt_name: "Museo Arqueologico",
        //     name: "Museo Inka",
        //     tourism: "museum"
        // }
        map.addSource('museums', {
            type: 'vector',
            url: 'mapbox://mapbox.2opop9hr'
        });
        map.addLayer({
            'id': 'museums',
            'type': 'circle',
            'source': 'museums',
            'layout': {
                // Make the layer visible by default.
                'visibility': 'visible'
            },
            'paint': {
                'circle-radius': 8,
                'circle-color': 'rgba(55,148,179,1)'
            },
            'source-layer': 'museum-cusco'
        });

        // Add the Mapbox Terrain v2 vector tileset. Read more about
        // the structure of data in this tileset in the documentation:
        // https://docs.mapbox.com/vector-tiles/reference/mapbox-terrain-v2/
        map.addSource('contours', {
            type: 'vector',
            url: 'mapbox://mapbox.mapbox-terrain-v2'
        });
        map.addLayer({
            'id': 'contours',
            'type': 'line',
            'source': 'contours',
            'source-layer': 'contour',
            'layout': {
                // Make the layer visible by default.
                'visibility': 'visible',
                'line-join': 'round',
                'line-cap': 'round'
            },
            'paint': {
                'line-color': '#877b59',
                'line-width': 1
            }
        });
    });

    // After the last frame rendered before the map enters an "idle" state.
    map.on('idle', () => {
        // If these two layers were not added to the map, abort
        if (!map.getLayer('contours') || !map.getLayer('museums')) {
            return;
        }

        // Enumerate ids of the layers.
        const toggleableLayerIds = ['contours', 'museums'];

        // Set up the corresponding toggle button for each layer.
        for (const id of toggleableLayerIds) {
            // Skip layers that already have a button set up.
            if (document.getElementById(id)) {
                continue;
            }

            // Create a link.
            const link = document.createElement('a');
            link.id = id;
            link.href = '#';
            link.textContent = id;
            link.className = 'active';

            // Show or hide layer when the toggle is clicked.
            link.onclick = function (e) {
                const clickedLayer = this.textContent;
                e.preventDefault();
                e.stopPropagation();

                const visibility = map.getLayoutProperty(
                    clickedLayer,
                    'visibility'
                );

                // Toggle layer visibility by changing the layout object's visibility property.
                if (visibility === 'visible') {
                    map.setLayoutProperty(clickedLayer, 'visibility', 'none');
                    this.className = '';
                } else {
                    this.className = 'active';
                    map.setLayoutProperty(
                        clickedLayer,
                        'visibility',
                        'visible'
                    );
                }
            };

            const layers = document.getElementById('menu');
            layers.appendChild(link);
        }
    });
</script>

</body>
</html>
```

**React**

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

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

const menuStyle = {
  background: '#fff',
  position: 'absolute',
  zIndex: 1,
  top: 10,
  right: 10,
  borderRadius: 3,
  width: '120px',
  border: '1px solid rgba(0, 0, 0, 0.4)',
  fontFamily: "'Open Sans', sans-serif"
};

const menuItemStyle = {
  fontSize: '13px',
  color: '#404040',
  display: 'block',
  margin: '0',
  padding: '10px',
  textDecoration: 'none',
  border: 'none',
  textAlign: 'center',
  cursor: 'pointer',
  width: '100%'
};

const activeMenuItemStyle = {
  backgroundColor: '#3887be',
  color: '#ffffff'
};

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

  const [activeLayerIds, setActiveLayerIds] = useState(['museums', 'contours']);
  const [mapLoaded, setMapLoaded] = useState(false);

  useEffect(() => {
    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,
      style: 'mapbox://styles/mapbox/standard',
      zoom: 15,
      center: [-71.97722138410576, -13.517379300798098]
    });

    mapRef.current.on('load', () => {
      setMapLoaded(true);
      mapRef.current.addSource('museums', {
        type: 'vector',
        url: 'mapbox://mapbox.2opop9hr'
      });
      mapRef.current.addLayer({
        id: 'museums',
        type: 'circle',
        source: 'museums',
        layout: {
          visibility: 'visible'
        },
        paint: {
          'circle-radius': 8,
          'circle-color': 'rgba(55,148,179,1)'
        },
        'source-layer': 'museum-cusco'
      });

      mapRef.current.addSource('contours', {
        type: 'vector',
        url: 'mapbox://mapbox.mapbox-terrain-v2'
      });
      mapRef.current.addLayer({
        id: 'contours',
        type: 'line',
        source: 'contours',
        'source-layer': 'contour',
        layout: {
          visibility: 'visible',
          'line-join': 'round',
          'line-cap': 'round'
        },
        paint: {
          'line-color': '#877b59',
          'line-width': 1
        }
      });
    });

    mapRef.current.on('idle', () => {
      if (
        !mapRef.current.getLayer('contours') ||
        !mapRef.current.getLayer('museums')
      ) {
        return;
      }
    });
  }, []);

  useEffect(() => {
    if (!mapLoaded) return;

    const allLayerIds = ['museums', 'contours'];

    // for each layerId, check whether it is included in activeLayerIds,
    // show and hide accordingly by setting layer visibility
    allLayerIds.forEach((layerId) => {
      if (activeLayerIds.includes(layerId)) {
        mapRef.current.setLayoutProperty(layerId, 'visibility', 'visible');
      } else {
        mapRef.current.setLayoutProperty(layerId, 'visibility', 'none');
      }
    });
  }, [activeLayerIds]);

  const handleClick = (e) => {
    const layerId = e.target.id;

    if (activeLayerIds.includes(layerId)) {
      setActiveLayerIds(activeLayerIds.filter((d) => d !== layerId));
    } else {
      setActiveLayerIds([...activeLayerIds, layerId]);
    }
  };

  return (
    <>
      <nav id="menu" style={menuStyle}>
        <button
          id="contours"
          style={{
            ...menuItemStyle,
            ...(activeLayerIds.includes('contours') && activeMenuItemStyle),
            borderBottom: '1px solid rgba(0, 0, 0, 0.25)' // add a bottom border to the first button
          }}
          onClick={handleClick}
        >
          contours
        </button>
        <button
          id="museums"
          style={{
            ...menuItemStyle,
            ...(activeLayerIds.includes('museums') && activeMenuItemStyle)
          }}
          onClick={handleClick}
        >
          museums
        </button>
      </nav>
      <div id="map" ref={mapContainerRef} style={{ height: '100%' }}></div>
    </>
  );
};

export default MapboxExample;
```