react-mapbox-gl icon indicating copy to clipboard operation
react-mapbox-gl copied to clipboard

How to change language of map labels in react-mapbox-gl?

Open dearamerican opened this issue 5 years ago • 9 comments

Mapbox docs give this clear example: https://docs.mapbox.com/mapbox-gl-js/example/language-switch/

react-mapbox-gl docs describe how to work with the original mapbox API: https://github.com/alex3165/react-mapbox-gl/blob/master/docs/API.md#using-the-original-mapbox-api

But I cannot change the language of my map labels by combining these two pieces of documentation. (I have tried both methods described for working with the original mapbox documentation.)

I've also tried Mapbox GL Language plugin: https://blog.mapbox.com/how-to-localize-your-maps-in-mapbox-gl-js-da4cc6749f47

Using Mapbox GL Language plugin as described (combined with the docs on how to interact with original mapbox API) wipes out map labels completely.

I'm clearly doing something (perhaps many things!) wrong.

Can someone point me in the right direction to learn how to localize a react-mapbox-gl map? Or even better: share a working code sample of how you implemented map localization with react-mapbox-gl?

Thank you!!

dearamerican avatar Dec 12 '19 23:12 dearamerican

@dearamerican do You have any luck with it? The same for me. I couldn't find approach to change language for react-mapbox-gl. Does anybody has information regarding it?

melamber avatar Jan 15 '20 08:01 melamber

@dearamerican @melamber Inspired by the snippet in this comment, here's how I changed the labels into Traditional Chinese.

import React from 'react';
import ReactMapboxGl from 'react-mapbox-gl';

const AwesomeMap = ReactMapboxGl({
    accessToken: process.env.REACT_APP_MAPBOX_TOKEN,
});

const changeMapLanguage = (map) => {
    map.getStyle().layers.forEach((layer) => {
        if (layer.id.endsWith('-label')) {
            map.setLayoutProperty(layer.id, 'text-field', [
                'coalesce',
                ['get', 'name_zh-Hant'],
                ['get', 'name'],
            ]);
        }
    });
};

const App = () => (
    <AwesomeMap
        style="mapbox://styles/mapbox/streets-v11"
        containerStyle={{ width: '100vw', height: '100vh' }}
        onStyleLoad={changeMapLanguage}
    >
        {/* Map Layers Here */}
    </AwesomeMap>
);

export default App;

mingjunlu avatar Mar 19 '20 08:03 mingjunlu

@mingjunlu Thanks - worked for me 😄

nataliahering avatar Nov 21 '20 20:11 nataliahering

@nataliahering No problem! I'm glad it helped 😄

mingjunlu avatar Nov 22 '20 05:11 mingjunlu

I am not sure why this is working for you, as only the labels are translated. You miss everything else, such as parks, cities, rivers (and all the others) which are not purely labels.

I found an alternative solution:

mapbox.current.getStyle().layers.forEach((layer) => {
  if (layer.layout && layer.layout['text-field']) {
    mapbox.current.setLayoutProperty(layer.id, 'text-field', [
      'coalesce',
      ['get', 'name_' + LOCALE],
      ['get', 'name'],
    ]);
  }
});

It would be nice if Mapbox comes with a proper solution, with a global option, for example. But for now, that will do :)

jordymeow avatar Jun 21 '21 23:06 jordymeow

The plugin works exactly as advertised, get a mapref and load it:

const mapRefCallback = useCallback((ref: MapRef | null) => {
    if (ref !== null) {
      //Set the actual ref we use elsewhere
      mapRef.current = ref;
      const map = ref;

      //Add language control that updates map text i18n based on browser preferences
      const language = new MapboxLanguage();
      map.addControl(language);

//...
 <Map
          {...mapSetting.viewState}
          ref={mapRefCallback}
 />

chriszrc avatar Oct 04 '22 19:10 chriszrc

@chriszrc

HI! Can you help me? where are you importing "new MapboxLanguage();" from? This code is`nt work for me

vladimirHlobshastyi avatar Oct 21 '22 06:10 vladimirHlobshastyi

@vladimirHlobshastyi it's mapbox's language plugin - https://github.com/mapbox/mapbox-gl-language

chriszrc avatar Oct 21 '22 14:10 chriszrc

maptiler plugin will work for this issue already checked! https://documentation.maptiler.com/hc/en-us/articles/4405445343889-How-to-set-the-language-for-your-map

map.getStyle().layers.forEach(function(thisLayer){ if(thisLayer.type == 'symbol'){ map.setLayoutProperty(thisLayer.id, 'text-field', ['get','name:' + language]) } })

sakshishinde2 avatar Mar 29 '23 06:03 sakshishinde2