Skip to content

feat/localize map(#1017)#1032

Merged
koala73 merged 4 commits intokoala73:mainfrom
FayezBast:feat/map-localization
Mar 5, 2026
Merged

feat/localize map(#1017)#1032
koala73 merged 4 commits intokoala73:mainfrom
FayezBast:feat/map-localization

Conversation

@FayezBast
Copy link
Contributor

@FayezBast FayezBast commented Mar 5, 2026

Summary

Localize MapLibre basemap labels to the user's UI language. Country names, cities, water bodies, and POI labels now render in the user's selected language (20 of 21 supported languages) with automatic fallback: localized name → English → native script.

Includes a self-hosted RTL text plugin to correctly render Arabic and other RTL scripts.

Closes #1017

CORS / CSP note

This PR self-hosts the Mapbox RTL text plugin under public/ (see public/mapbox-gl-rtl-text.min.js) to avoid CSP/CORS issues that can occur when loading the plugin from Mapbox’s CDN. The localization logic only changes symbol-layer text-field expressions and does not introduce new tile/style origins.

Type of change

  • New feature

Affected areas

  • Map / Globe
  • Other: Basemap localization

Checklist

  • Tested on worldmonitor.app variant
  • Tested on tech.worldmonitor.app variant (if applicable)
  • No API keys or secrets committed
  • TypeScript compiles without errors (npm run typecheck)
  • Unit tests pass (tests/map-locale.test.mts)
  • No regressions in existing test suite

Screenshots

Switch language in Settings → Language (e.g., Chinese, Arabic, French) and reload the page.
Map labels update automatically to the selected language.

@vercel
Copy link

vercel bot commented Mar 5, 2026

@FayezBast is attempting to deploy a commit to the Elie Team on Vercel.

A member of the Team first needs to authorize it.

@koala73
Copy link
Owner

koala73 commented Mar 5, 2026

Thanks for the solid work on this, Fayez! The extracted utility + test coverage is a big improvement over the inline approach. A couple of requests before merging:

  1. RTL plugin provenancepublic/mapbox-gl-rtl-text.min.js has no version or source URL. Can you add a comment at the top noting where it was downloaded from and what version it is? (e.g., @mapbox/mapbox-gl-rtl-text v0.3.0 from npm/GitHub)

  2. Remove comments — The project follows a minimal-comment style. Please strip the JSDoc blocks and inline comments from map-locale.ts — the function/variable names are self-explanatory. Keep only the // vi note in the language map since that documents a non-obvious omission.

@FayezBast
Copy link
Contributor Author

done

Copy link
Owner

@koala73 koala73 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ What's Good

  • Clean extraction: map-locale.ts is 88 lines, single responsibility, well-structured
  • Fallback chain: coalesce(localized → English → native) is the correct approach
  • RTL plugin: Self-hosted in public/ avoids CSP issues — good pattern for this repo
  • Test coverage: 416 lines, covers edge cases (null maps, empty layers, idempotency, RTL), uses both English and Arabic module instances
  • Integration: Called at both map.on('load') and style.load (theme switch) — covers all lifecycle points
  • Improvement over #1027: Uses name:en (colon, correct for CARTO tiles) instead of name_en (underscore). Also localizes ALL symbol layers, not just source-layer: 'place'

⚠️ Action Items

[ACTION 1] — RTL plugin guard

if (!maplibregl.getRTLTextPluginStatus || maplibregl.getRTLTextPluginStatus() === 'unavailable') {

The !maplibregl.getRTLTextPluginStatus check suggests guarding against older MapLibre versions that don't have the function. But package.json pins ^5.16.0 which definitely has it.

👉 Remove the unnecessary null check — it adds confusion about what versions are supported. Just use:

if (maplibregl.getRTLTextPluginStatus() === 'unavailable') {

[ACTION 2] — Empty line at top of map-locale.ts
Line 1 is blank before the import statement.

👉 Remove the leading blank line.

[ACTION 3] — Vietnamese fallback documentation
Vietnamese (vi) silently falls back to English with only a code comment. Users switching to Vietnamese will see English map labels with no indication why.

[ACTION 4] — type Expression = any
Loose typing on the expression type.

👉 Optional but recommended: Replace with type Expression = unknown[] or type Expression = [string, ...unknown[]] for basic shape safety.

📋 Verified

  • ✅ RTL plugin API: setRTLTextPlugin(url, lazy) — confirmed correct for MapLibre v5.16.0
  • name:en field syntax — correct for CARTO vector tiles (OpenMapTiles schema)
  • ✅ No clock auto-translation churn interaction — PR #1034 (translate="no") is about browser auto-translate, completely unrelated to this map localization
  • ✅ No infinite loop risk — setLayoutProperty does NOT re-trigger style.load

@FayezBast thx

@FayezBast
Copy link
Contributor Author

FayezBast commented Mar 5, 2026

u need me to fix what u addressed ? or khalas done

@koala73
Copy link
Owner

koala73 commented Mar 5, 2026

Pls do
I reduced the list

Copy link
Owner

@koala73 koala73 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All Good

@koala73 koala73 merged commit ca131bb into koala73:main Mar 5, 2026
1 of 2 checks passed
aldoyh pushed a commit to aldoyh/worldmonitor that referenced this pull request Mar 6, 2026
* feat/localize map(koala73#1017)

* feat :map localization

* fix: address map-localizatio
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Localize the Actual Map

2 participants