Skip to content

Both copy text to your clipboard — Build with AI copies a setup prompt to paste into Claude Code, Cursor, Codex or Copilot; Copy page as Markdown copies this page to paste into a chat. How it works

RTL Text

MapMetrics GL renders label text with a general-purpose text shaper. On its own, that shaper does not perform the glyph joining/reordering that Arabic, Hebrew, Persian and Urdu need. Without the RTL plugin, labels in those scripts render as disconnected, incorrectly-ordered characters — and the map does not throw an error. Nothing in the console tells you this is happening; the map just looks wrong for a subset of your users.

If your map (or your users' input) can contain Arabic, Hebrew, Persian or Urdu text, load the RTL plugin before you create the Map.

Loading the plugin

The plugin ships separately from the SDK

The SDK bundle contains the loader, not the plugin itself — you always pass a URL. MapMetrics hosts a ready-to-use build on its CDN, so you don't need to supply your own:

https://cdn.mapmetrics-atlas.net/basemaps-assets/js/mapmetrics-gl-rtl-text.min.js

If your deployment can't reach that CDN (an air-gapped network, or a strict worker-src/CSP allowlist), copy that build to your own origin and point setRTLTextPlugin at your copy instead.

js
mapmetricsgl.setRTLTextPlugin(
  'https://cdn.mapmetrics-atlas.net/basemaps-assets/js/mapmetrics-gl-rtl-text.min.js',
  false // lazy
);

const map = new mapmetricsgl.Map({
  container: 'map',
  style: 'https://gateway.mapmetrics-atlas.net/styles/?fileName=YOUR_STYLE_ID/YOUR_STYLE.json&token=YOUR_API_KEY',
  center: [0, 0],
  zoom: 2,
});

setRTLTextPlugin(url, lazy):

  • url — where to fetch the plugin script from. It's loaded from a worker via importScripts, so it must be reachable from your page (a plugin bundle hosted on a CDN, or one you serve yourself).
  • lazy — if false (or omitted), the plugin is fetched and initialized immediately. If true, loading is deferred until the map actually encounters a tile that needs RTL shaping.

Call it once, before you create your first Map instance. Calling it a second time throws setRTLTextPlugin cannot be called multiple times.

Checking status

js
mapmetricsgl.getRTLTextPluginStatus();
// 'unavailable' | 'deferred' | 'requested' | 'loading' | 'loaded' | 'error'

The statuses:

StatusMeaning
unavailableNot loaded, and setRTLTextPlugin hasn't been called.
deferredURL is registered, but loading was deferred (lazy: true) and hasn't been triggered yet.
requestedA tile needed RTL shaping before the plugin was set.
loadingThe worker is fetching/initializing the plugin.
loadedReady — RTL scripts will shape correctly.
errorThe plugin failed to load (bad URL, network failure, etc.).

Why "lazy" exists

If most of your users never see RTL text, set lazy: true so the extra script isn't fetched on every page load — it's pulled in only the first time a tile actually needs it. If you know your map will regularly show Arabic, Hebrew, Persian or Urdu labels, pass false so shaping is correct from the very first render.