Internationalisation¶
The ecosystem's products and documentation are served in several languages. This page explains the language policy and how it is implemented technically.
Language policy¶
| Level | Languages |
|---|---|
| Mandatory | Монгол (mn) · English (en) |
| For the main products | + 中文 (zh) · Русский (ru) |
| For ecosystem-level documentation | Mongolian + the six official UN languages |
Mongolian is the source language — the original text is written in Mongolian and translated outwards.
The six official languages of the United Nations are: العربية (ar) · 中文
(zh) · English (en) · Français (fr) · Русский (ru) · Español (es).
This site (ecosystem-level documentation) is served in Mongolian plus those six
— seven languages in total.
Why exactly these languages?
The readers of ecosystem-level documentation are not only in-house developers: they include international partners, donor organisations, standards bodies and foreign integrators. The six UN languages give the widest global reach and are a neutral choice that privileges no single country.
The deep technical documentation of an individual platform (endpoint schemas, SDK reference) is out of scope for this policy — it stays MN + EN inside its own repository.
i18n in the products¶
Applications determine the user's language in this order:
- The user's own setting (stored in their profile),
- The browser's
Accept-Language, - The default language (
mn).
The AI assistant replies in the user's language — whichever language the question arrived in.
Two dictionary layers¶
The dictionary lives in two places, and understanding the boundary matters:
| Dictionary | Where | Size |
|---|---|---|
| Shared — login, navigation, admin, eID | @gerege/ui-core |
846 keys × 7 languages |
| Platform — the terminology of that domain | lib/<platform>I18n.ts |
Varies per platform, usually 2–4 languages |
The rule: the shared dictionary only knows the shared surface. The wallet's IBAN/statement vocabulary, the developer portal's API catalogue, Ring's business-process terminology — those belong in the app's own dictionary.
The reason is cost: put Ring's 1,104 terms into the shared dictionary and kiosk, POS and the wallet all carry them — and every language added multiplies that cost sevenfold.
A platform dictionary falls back to English for the languages it has not translated — so the interface can be available in seven languages while the marketing copy and the domain terminology exist in fewer.
Interface language ≠ content language
Growing the dictionary from four languages to seven broke every place that
said Record<Lang, …>: the landing page's marketing copy, the API catalogue
descriptions — these are written by humans and do not scale the way the
interface does. In such places, declare the language set explicitly, as
something like LANDING_LANGS.
i18n in the documentation¶
Each repository's documentation site uses MkDocs Material +
mkdocs-static-i18n.
The suffix layout¶
Translations are made by adding a language code to the file name:
docs/
├── index.md ← Монгол (default)
├── index.ar.md ← العربية
├── index.zh.md ← 中文
├── index.en.md ← English
├── index.fr.md ← Français
├── index.ru.md ← Русский
└── index.es.md ← Español
Configuration:
plugins:
- i18n:
docs_structure: suffix
fallback_to_default: true
reconfigure_material: true
reconfigure_search: true
languages:
- locale: mn
default: true
name: Монгол
build: true
- locale: en
name: English
build: true
- locale: ar
name: العربية
build: true
# … zh · fr · ru · es likewise
The default language builds at the site root (/), the others under a
sub-path (/en/, /ar/, /zh/, /fr/, /ru/, /es/).
Fallback¶
fallback_to_default: true — an untranslated page shows its content in the
default language. So even with translations missing, the site stays
whole and no 404 appears.
This is the practical choice: documentation grows constantly and translation lags behind. Waiting until every page is translated at once amounts to not publishing the documentation at all.
Nav translation¶
Menu labels live in mkdocs.yml rather than in page content, so they are
translated separately for each locale:
- locale: en
nav_translations:
Архитектур: Architecture
Платформууд: Platforms
- locale: ar
nav_translations:
Архитектур: البنية المعمارية
Платформууд: المنصّات
If you add a page and forget to add its nav_translations entry for all six
locales, that menu label stays in Mongolian — the build does not fail, so it
only shows up on inspection.
Right-to-left text (RTL)¶
العربية reads right to left. Material recognises the ar locale, sets
<html dir="rtl"> and flips the menu, headings and table flow by itself — no
separate direction setting is needed.
Code blocks and ASCII diagrams, however, stay left-to-right even in RTL. That is correct: technical notation (URLs, commands, YAML) loses its meaning if its direction is reversed.
Anchors for Cyrillic headings¶
The standard slugify drops Cyrillic letters
Python-Markdown's default toc slugify deletes non-ASCII characters.
As a result the heading ## Танилт receives an empty id and the
in-page link (#танилт) stops working.
The fix is a slugify that preserves unicode:
This site is configured the same way.
The order of translation¶
When adding new documentation:
- Write the source text in Mongolian — the source is always Mongolian.
- Stabilise the Mongolian version with a strict build (links and anchors get checked).
- Then translate into all six languages at once. Translating a page only partly leaves the languages out of step with each other.
Finish one page in every language
It is better to work page by page than language by language: converting one document into six languages at the same time keeps the terminology, the structure and the table rows identical. Going the other way — "English for every page first" — means the languages translated later will be chasing a source text that has already changed.
What gets translated and what does not¶
| Translated | Left as-is |
|---|---|
| Body text, headings, table values | Domain names (sso.gerege.mn) |
| Explanations, warnings, tips | Repository names (template-gerege-mn) |
| Descriptive labels inside diagrams | Code, YAML, commands, endpoint paths |
| Table headers | Product names (eID Mongolia, G-Sign) |
| Status-badge text | Standard names (OIDC, PKCE, RFC 3161) |
File names and directory structure are never translated — it is
platforms/sso.ru.md, not платформы/sso.md. That way the URL path stays the
same when switching languages, and deep links keep working.
The state of this site¶
Every page of the ecosystem-level documentation is ready in seven languages:
| Locale | Language | Path | State |
|---|---|---|---|
mn |
Монгол (default) | / |
✅ complete |
ar |
العربية | /ar/ |
✅ complete |
zh |
中文 | /zh/ |
✅ complete |
en |
English | /en/ |
✅ complete |
fr |
Français | /fr/ |
✅ complete |
ru |
Русский | /ru/ |
✅ complete |
es |
Español | /es/ |
✅ complete |
fallback_to_default remains switched on — when a new page is added and its
translation lags behind, that page shows the Mongolian original and the site
stays whole.
If you spot an error or an awkward phrasing, please send a PR to the repository — see This docs platform.