Skip to content

Add a New Layer Below Labels ​

Use the beforeId parameter in addLayer() to insert layers below map labels so they stay readable.

Insert a Layer Below Labels ​

javascript
map.on('load', () => {
  // Find the first symbol (label) layer in the style
  const layers = map.getStyle().layers;
  let firstSymbolId;
  for (const layer of layers) {
    if (layer.type === 'symbol') {
      firstSymbolId = layer.id;
      break;
    }
  }

  map.addSource('my-source', { type: 'geojson', data: myGeoJSON });

  // Pass firstSymbolId as the second argument to insert below labels
  map.addLayer({
    id: 'my-fill',
    type: 'fill',
    source: 'my-source',
    paint: { 'fill-color': '#3b82f6', 'fill-opacity': 0.4 }
  }, firstSymbolId);
});

Insert Before a Specific Layer ​

javascript
// Insert before a known layer ID
map.addLayer({ id: 'my-layer', type: 'fill', source: 'my-source', paint: {} }, 'road-label');

// Insert at the very bottom (no beforeId = on top)
map.addLayer({ id: 'my-layer', type: 'fill', source: 'my-source', paint: {} });

Complete Example ​

html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <link href="https://cdn.mapmetrics-atlas.net/versions/latest/mapmetrics-gl.css" rel="stylesheet" />
    <script src="https://cdn.mapmetrics-atlas.net/versions/latest/mapmetrics-gl.js"></script>
    <style>#map { height: 500px; width: 100%; }</style>
  </head>
  <body>
    <div id="map"></div>
    <script>
      const map = new mapmetricsgl.Map({ container: 'map', style: '<StyleFile_URL_with_Token>', center: [2.35, 48.85], zoom: 4 });
      map.on('load', () => {
        const layers = map.getStyle().layers;
        const firstSymbolId = layers.find(l => l.type === 'symbol')?.id;

        map.addSource('polygon', {
          type: 'geojson',
          data: { type: 'Feature', geometry: { type: 'Polygon', coordinates: [[[-4.5,48],[8.2,48],[7.5,43.5],[3,42.5],[-1.8,43.4],[-4.5,48]]] } }
        });
        map.addLayer({ id: 'polygon-fill', type: 'fill', source: 'polygon', paint: { 'fill-color': '#3b82f6', 'fill-opacity': 0.4 } }, firstSymbolId);
      });
    </script>
  </body>
</html>
jsx
import React, { useEffect, useRef } from 'react';
import mapmetricsgl from '@mapmetrics/mapmetrics-gl';
import '@mapmetrics/mapmetrics-gl/dist/mapmetrics-gl.css';

const LayerBelowLabels = () => {
  const mapContainer = useRef(null);
  const map = useRef(null);

  useEffect(() => {
    if (map.current) return;
    map.current = new mapmetricsgl.Map({ container: mapContainer.current, style: '<StyleFile_URL_with_Token>', center: [2.35, 48.85], zoom: 4 });
    map.current.on('load', () => {
      const layers = map.current.getStyle().layers;
      const firstSymbolId = layers.find(l => l.type === 'symbol')?.id;
      map.current.addSource('polygon', {
        type: 'geojson',
        data: { type: 'Feature', geometry: { type: 'Polygon', coordinates: [[[-4.5,48],[8.2,48],[7.5,43.5],[3,42.5],[-1.8,43.4],[-4.5,48]]] } }
      });
      map.current.addLayer({ id: 'polygon-fill', type: 'fill', source: 'polygon', paint: { 'fill-color': '#3b82f6', 'fill-opacity': 0.4 } }, firstSymbolId);
    });
    return () => { map.current?.remove(); map.current = null; };
  }, []);

  return <div ref={mapContainer} style={{ height: '500px', width: '100%' }} />;
};

export default LayerBelowLabels;

For more information, visit the MapMetrics GitHub repository.