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

# Replace a label in the Mapbox Standard Style

This example demonstrates an advanced technique for replacing a single place label in the [Mapbox Standard Style](https://docs.mapbox.com/map-styles/guides/standard-styles/) with custom text. Because the Standard style's internal layers are not directly editable, the technique works by [importing](https://docs.mapbox.com/style-spec/reference/imports/) Standard into a top-level style that adds a GeoJSON source with a replacement feature and a hard coded `settlement-major-label` layer.

The replacement feature's coordinates and properties must match those of the original feature in the `place_label` source layer of the [Mapbox Streets tileset](https://docs.mapbox.com/data/tilesets/reference/mapbox-streets-v8/) — fields like `symbolrank`, `text_anchor`, and `capital` control zoom visibility and symbol placement. The renderer's symbol placement engine suppresses the original label when the replacement occupies the same location.

The hard coded layer definition targets `symbolrank=6`, `capital=0`, `lightPreset=day`, and `theme=default`. If the Standard style's `settlement-major-label` layer changes in a future release, the layer definition will need to be updated to match.

> Example code:

**JavaScript**

```html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Replace a label in the 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.32.0/mapbox-gl.css" rel="stylesheet">
<script src="https://api.mapbox.com/mapbox-gl-js/v3.32.0/mapbox-gl.js"></script>
<style>
body { margin: 0; padding: 0; }
#map { position: absolute; top: 0; bottom: 0; width: 100%; }
</style>
</head>
<body>
<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',
        style: {
            version: 8,
            // The sprite and glyphs URLs must match the Standard style's assets
            // so that dot icons and fonts used by settlement labels resolve correctly.
            sprite: 'mapbox://sprites/mapbox/standard/7ixcpyhbhz67em71mmpln1klo',
            glyphs: 'mapbox://fonts/mapbox/{fontstack}/{range}.pbf',
            sources: {
                // Replacement label feature. Coordinates and properties must match the
                // original Streets tileset feature so the layer styles it correctly.
                'nyc-label-point': {
                    type: 'geojson',
                    data: {
                        type: 'FeatureCollection',
                        features: [
                            {
                                type: 'Feature',
                                geometry: {
                                    type: 'Point',
                                    coordinates: [
                                        -74.00596618652344, 40.71278477995827
                                    ]
                                },
                                properties: {
                                    name: 'New Amsterdam',
                                    name_en: 'New Amsterdam',
                                    filterrank: 1,
                                    class: 'settlement',
                                    worldview: 'all',
                                    symbolrank: 6,
                                    text_anchor: 'left',
                                    capital: 0
                                }
                            }
                        ]
                    }
                }
            },
            // Based on settlement-major-label from the Mapbox Standard style, simplified for a
            // symbolrank=6, capital=0 settlement with lightPreset=day, theme=default:
            //   - All ["config", ...] expressions resolved to their default values
            //   - filter: symbolrank=6 passes z2–12 only, collapsed to a single step
            //   - text-size: symbolrank=6 always resolves the same branch at each zoom stop
            //   - text-font: ["concat", ["config", "font"], " Medium"] → "DIN Pro Medium"
            //   - text-color / text-halo-color: resolved from day lightPreset defaults
            layers: [
                {
                    id: 'settlement-major-label',
                    type: 'symbol',
                    source: 'nyc-label-point',
                    minzoom: 2,
                    maxzoom: 15,
                    filter: ['step', ['zoom'], false, 2, true, 13, false],
                    layout: {
                        'text-line-height': 1.1,
                        'text-size': [
                            'interpolate',
                            ['cubic-bezier', 0.2, 0, 0.9, 1],
                            ['zoom'],
                            3,
                            11,
                            6,
                            16,
                            8,
                            20,
                            15,
                            24
                        ],
                        'text-radial-offset': ['step', ['zoom'], 0.55, 8, 0],
                        'symbol-sort-key': ['get', 'symbolrank'],
                        'icon-image': [
                            'step',
                            ['zoom'],
                            [
                                'image',
                                'dot-11',
                                {
                                    params: {
                                        'color-primary': 'hsl(0, 0%, 0%)',
                                        'color-secondary':
                                            'hsla(0, 0%, 100%, 1)'
                                    }
                                }
                            ],
                            8,
                            ''
                        ],
                        'text-font': [
                            'DIN Pro Medium',
                            'Arial Unicode MS Bold'
                        ],
                        'text-justify': [
                            'step',
                            ['zoom'],
                            [
                                'match',
                                ['get', 'text_anchor'],
                                ['left', 'bottom-left', 'top-left'],
                                'left',
                                ['right', 'bottom-right', 'top-right'],
                                'right',
                                'center'
                            ],
                            8,
                            'center'
                        ],
                        'text-anchor': [
                            'step',
                            ['zoom'],
                            ['get', 'text_anchor'],
                            8,
                            'center'
                        ],
                        'text-field': [
                            'coalesce',
                            ['get', 'name_en'],
                            ['get', 'name']
                        ],
                        'text-max-width': 7
                    },
                    paint: {
                        'text-opacity': [
                            'case',
                            ['to-boolean', ['feature-state', 'hide']],
                            0,
                            1
                        ],
                        'icon-opacity': [
                            'case',
                            ['to-boolean', ['feature-state', 'hide']],
                            0,
                            1
                        ],
                        'text-color': 'hsl(0, 0%, 0%)',
                        'text-halo-color': 'hsla(0, 0%, 100%, 1)',
                        'text-halo-width': 1,
                        'text-halo-blur': 1
                    }
                }
            ],
            // Import the Standard style as a basemap — this is what makes the technique work
            imports: [{ id: 'basemap', url: 'mapbox://styles/mapbox/standard' }]
        },
        center: [-74.006, 40.7128],
        zoom: 10
    });
</script>

</body>
</html>
```

**React**

```jsx
import React, { 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);

  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,
      style: {
        version: 8,
        // The sprite and glyphs URLs must match the Standard style's assets
        // so that dot icons and fonts used by settlement labels resolve correctly.
        sprite: 'mapbox://sprites/mapbox/standard/7ixcpyhbhz67em71mmpln1klo',
        glyphs: 'mapbox://fonts/mapbox/{fontstack}/{range}.pbf',
        sources: {
          // Replacement label feature. Coordinates and properties must match the
          // original Streets tileset feature so the layer styles it correctly.
          'nyc-label-point': {
            type: 'geojson',
            data: {
              type: 'FeatureCollection',
              features: [
                {
                  type: 'Feature',
                  geometry: {
                    type: 'Point',
                    coordinates: [-74.00596618652344, 40.71278477995827]
                  },
                  properties: {
                    name: 'New Amsterdam',
                    name_en: 'New Amsterdam',
                    filterrank: 1,
                    class: 'settlement',
                    worldview: 'all',
                    symbolrank: 6,
                    text_anchor: 'left',
                    capital: 0
                  }
                }
              ]
            }
          }
        },
        // Based on settlement-major-label from the Mapbox Standard style, simplified for a
        // symbolrank=6, capital=0 settlement with lightPreset=day, theme=default:
        //   - All ["config", ...] expressions resolved to their default values
        //   - filter: symbolrank=6 passes z2–12 only, collapsed to a single step
        //   - text-size: symbolrank=6 always resolves the same branch at each zoom stop
        //   - text-font: ["concat", ["config", "font"], " Medium"] → "DIN Pro Medium"
        //   - text-color / text-halo-color: resolved from day lightPreset defaults
        layers: [
          {
            id: 'settlement-major-label',
            type: 'symbol',
            source: 'nyc-label-point',
            minzoom: 2,
            maxzoom: 15,
            filter: ['step', ['zoom'], false, 2, true, 13, false],
            layout: {
              'text-line-height': 1.1,
              'text-size': [
                'interpolate',
                ['cubic-bezier', 0.2, 0, 0.9, 1],
                ['zoom'],
                3,
                11,
                6,
                16,
                8,
                20,
                15,
                24
              ],
              'text-radial-offset': ['step', ['zoom'], 0.55, 8, 0],
              'symbol-sort-key': ['get', 'symbolrank'],
              'icon-image': [
                'step',
                ['zoom'],
                [
                  'image',
                  'dot-11',
                  {
                    params: {
                      'color-primary': 'hsl(0, 0%, 0%)',
                      'color-secondary': 'hsla(0, 0%, 100%, 1)'
                    }
                  }
                ],
                8,
                ''
              ],
              'text-font': ['DIN Pro Medium', 'Arial Unicode MS Bold'],
              'text-justify': [
                'step',
                ['zoom'],
                [
                  'match',
                  ['get', 'text_anchor'],
                  ['left', 'bottom-left', 'top-left'],
                  'left',
                  ['right', 'bottom-right', 'top-right'],
                  'right',
                  'center'
                ],
                8,
                'center'
              ],
              'text-anchor': [
                'step',
                ['zoom'],
                ['get', 'text_anchor'],
                8,
                'center'
              ],
              'text-field': ['coalesce', ['get', 'name_en'], ['get', 'name']],
              'text-max-width': 7
            },
            paint: {
              'text-opacity': [
                'case',
                ['to-boolean', ['feature-state', 'hide']],
                0,
                1
              ],
              'icon-opacity': [
                'case',
                ['to-boolean', ['feature-state', 'hide']],
                0,
                1
              ],
              'text-color': 'hsl(0, 0%, 0%)',
              'text-halo-color': 'hsla(0, 0%, 100%, 1)',
              'text-halo-width': 1,
              'text-halo-blur': 1
            }
          }
        ],
        // Import the Standard style as a basemap — this is what makes the technique work
        imports: [{ id: 'basemap', url: 'mapbox://styles/mapbox/standard' }]
      },
      center: [-74.006, 40.7128],
      zoom: 10
    }));

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

  return (
    <div ref={mapContainerRef} style={{ width: '100%', height: '100%' }} />
  );
};

export default MapboxExample;
```