Skip to content

Change a map's language

Replicates the MapLibre example Change a map’s language. The labels being translated belong to the basemap style, which the document references but does not author. Rewriting their text-field is therefore runtime work: the buttons in a corner slot point every symbol layer that reads a name at name:<lang>, falling back to the local name.

Pick a language — country and place labels switch
change-a-maps-language.yaml
# yaml-language-server: $schema=https://docs.maplibre-yaml.org/schema/latest/map.schema.json
# Gallery twin of https://maplibre.org/maplibre-gl-js/docs/examples/change-a-maps-language/
# The YAML half: just the map. The labels being translated belong to the
# BASEMAP style, which the document references but does not author, so
# rewriting their text-field is runtime work — see change-a-maps-language.js.
# (Labels a document authors itself could read a `global-state` language
# key instead, driven by an enum parameter with no JS at all.)
type: map
id: change-a-maps-language
config:
center: [16.05, 48]
zoom: 2.9
mapStyle: "https://tiles.openfreemap.org/styles/bright"

This markup goes inside <ml-map>; children with a slot ride its corner system.

change-a-maps-language.html
<div slot="top-left" class="gallery-panel" data-languages>
<button type="button" data-lang="fr">French</button>
<button type="button" data-lang="ru">Russian</button>
<button type="button" data-lang="de">German</button>
<button type="button" data-lang="es">Spanish</button>
</div>
change-a-maps-language.js
// The JavaScript half: setLayoutProperty on the basemap's own label layers.
// Every symbol layer whose text-field reads a name is pointed at
// `name:<lang>`, falling back to the local name where a feature has no
// translation (upstream patches three country-label layers by id; this
// works on any OpenMapTiles-schema basemap).
const mapEl = document.querySelector("ml-map");
document.querySelector("[data-languages]").addEventListener("click", async (e) => {
const lang = e.target.closest("[data-lang]")?.dataset.lang;
if (!lang) return;
const map = await mapEl.mapReady();
for (const layer of map.getStyle().layers) {
if (layer.type !== "symbol") continue;
const field = map.getLayoutProperty(layer.id, "text-field");
if (field && JSON.stringify(field).includes("name")) {
map.setLayoutProperty(layer.id, "text-field", [
"coalesce",
["get", `name:${lang}`],
["get", "name"],
]);
}
}
});
  • Upstream patches three country-label layers by id; checking each symbol layer’s text-field for a name works on any OpenMapTiles-schema basemap.
  • Labels the document authors itself need no JS: a text-field reading ["get", ["concat", "name:", ["global-state", "lang"]]] plus an enum parameter does it declaratively.