GH GambleHub

Multilingual interfaces and localization

1) Principles

1. Language is not skin. Texts, formats, direction of writing, illustrations, legal blocks and even navigation are changing.
2. First the keys, then the texts. Structure semantic keys and parameters - translations come later.
3. Pseudolocalization - before exit. Catch overflows, "hard-sewn" lines and hidden anglicisms.
4. Folbacks are predictable. 'ru-UA → ru → en'. No "quiet" failures.
5. Security. No HTML from translation to DOM without sanitization; placeholders are positional/named only.
6. A11y-equivalence. Alt texts, aria labels, abbreviations - everything is localized.


2) Locale strategy

System codes: 'language-REGION' (for example, 'pt-BR', 'en-GB').
Locale selection: user profile → setting; spare - auto-detection by browser/geo (with confirmation).
Multi-region: distinguish language from law: 'es-ES' ≠ 'es-MX' (different laws/payments/limits).
Folback chain: UI is the nearest language; legal texts - strictly regional version, otherwise block and confirmation request.


3) Information architecture and content

Key areas: navigation, CTA, bugs, forms, prompts, notifications, letters, PDF/banners.
Text extensions: + 30-40% width reserve (German/Finnish). Layout - elastic (flex/grid).
Tone/style: brand dictionary (terms, without "slang translation" in critical places).
Images/icons: avoid text in pictures; if needed, keep local versions.


4) i18n architecture

Keys: 'domain. section. intent` → `payments. withdraw. error. insufficient_funds`.
Placeholders: named ('{amount}', '{minutes}'), formatted out of line.
ICU MessageFormat: multiplicity, gender, concordance.
Files: by locale and domains ('/i18n/{ locale }/{ domain} .json '), chunks are loaded lazily.
Server/client: universal render, locale in cookie + HTTP-Vary.

Example key (ICU):
json
{
"betslip": {
"placed": "Ставка на сумму {amount} {currency} принята",
"timeout": "Ожидаем подтверждение… ~{seconds, plural, one {# сек} few {# сек} many {# сек} other {# сек}}"
}
}

5) Formatting: numbers, dates, currencies, units

Use'Intl. ':
js const nf = new Intl.NumberFormat('uk-UA', { style:'currency', currency:'UAH' });
nf.format(2000); // 2 000,00 ₴

const df = new Intl.DateTimeFormat('tr-TR', { dateStyle:'medium', timeStyle:'short' });
df.format(new Date());

const pl = new Intl.PluralRules('ru-RU');

Minor units: Keep amounts in cents/kopecks; Format on the client.
Relative time: 'Intl. RelativeTimeFormat`.
Units: 'Intl. NumberFormat({ style:'unit', unit:'meter' })`.
Calendar/week: 1st day of the week and date format - by locale.


6) RTL and writing direction

Support 'dir = "rtl"' for 'ar', 'he', 'fa'; use'dir = "auto" 'for custom content.
Invert icons/chevrons; carousel and stepper mirrors.
Currency numbers/symbols - LTR windows (avoid mixed BiDi chaos).
CSS Boolean properties ('inline-start/end') instead of left/right.


7) Forms and input

Names/addresses: allow apostrophes/diacritics/double surnames.
Telephones: E.164 storage; masks - soft, with insert support.
Address formats: field order by country; index/state may be missing.
Keyboards: 'inputmode', 'autocomplete' correct for locale.
Placeholders: examples in local language/format.


8) Pseudolocalization and testing

Automatically replace the lines with '【 ěļő 】' + extension '+ + +' (~ 35%).
Include the pseudolocal in the dev assembly as' qps-ploc '.
Screenshots with context for translators: highlighting placeholders and long texts.
Test: trimmings, hyphenations, overflows, "hard-stitched" strings, RTL.


9) Notifications, letters, templates

Template of letter and subject - for each locale; separate texts and layout.
Dates/amounts in the subject - formatted by locale.
The Configure Notifications links are always in the language of the letter.
SMS: short, without multiline quotes; UTM - no localization.


10) Safety and reliability

Never interpret the translation as HTML, use safe inserts.
Placeholders - only data, not markup.
Logs/metrics are unclassified, but with a locale for tracing problems.
Folback when the translation file is not available - "quiet" (show English + telemetry).


11) Performance

Chunks of transfers by routes/domains; preload for frequent.
Кеш CDN с `ETag`/`Cache-Control`.
Avoid rerenders when changing locales - i18n context with memoization.


12) The specifics of iGaming

Disclaimers and responsible play: the wording depends on the country (18 +/21 +, regulatory authorities, help lines).
KYC/AML: legally correct terms (for example, "Source of Funds," "Beneficial Owner"), case/birth options.
Payment methods: local names (PIX, Papara, SEPA) and conditions (ETA/commissions) - strictly by region.
Coefficients and format: 'decimal/fractional/american' - local explanations and example.
Legal texts: unchanged regional versions; banning folbeck from other jurisdiction.


13) Design system tokens (example)

json
{
"i18n": {
"fallback": ["en"],
"rtl": ["ar", "he", "fa"],
"textExpansionPct": 0.35,
"screenshotHints": true
},
"typography": {
"lineHeight": { "ui": 1.4, "dense": 1.3 },
"hyphens": "auto",
"tabularNums": true
},
"layout": {
"minLabelWidth": 96,
"gap": { "sm": 8, "md": 12, "lg": 16 }
},
"a11y": {
"ariaMirroring": true,
"altTranslate": true,
"contrastAA": true
}
}

14) Snippets

React + i18next (lazy boot, ICU):
ts import i18n from 'i18next';
import ICU from 'i18next-icu';
import { initReactI18next } from 'react-i18next';

i18n.use(ICU).use(initReactI18next).init({
lng: 'uk-UA',
fallbackLng: ['ru', 'en'],
load: 'languageOnly',
interpolation: { escapeValue: false },
resources: {} // пусто — грузим лениво
});

export async function loadNamespace(ns: string, lng = i18n.language){
const mod = await import(`/i18n/${lng}/${ns}.json`);
i18n.addResourceBundle(lng, ns, mod.default, true, true);
}
ICU pluralization (rus/ukr):
json
{
"notifications": "{count, plural, one {# уведомление} few {# уведомления} many {# уведомлений} other {# уведомления}}"
}
Intl for currencies/dates:
js const money = (v, c, l) => new Intl.NumberFormat(l, {style:'currency', currency:c}).format(v/100);
const rel = (v, unit, l) => new Intl.RelativeTimeFormat(l, {numeric:'auto'}).format(v, unit);
// money(250000,'EUR','de-DE') → 2.500,00 €
RTL class at the root:
js const rtl = new Set(['ar','he','fa']);
document.documentElement.dir = rtl.has(locale.split('-')[0])? 'rtl': 'ltr';
Pseudolocal (dev):
js const pseudo = s => s.replace(/[aAeEiIoOuU]/g, m => ({a:'à',e:'ê',i:'ï',o:'ô',u:'û'}[m.toLowerCase()]        m)).replace(/([^\s])/g,'$1\u0301');

15) Empty/error/graysful degradation

There is no key translation: we show English + log 'missing _ key'.

No locale file: folback and banner "Part of the interface in English."

Text too long: multi-line, 'line-clamp' in place, tooltip with full text.


16) Metrics and quality control

Coverage% by key/location (target ≥ 98%).
Time-to-Translate (TTT) for new releases.
Bug rate L10n: visual clippings, RTL defects, erroneous formats.
Reading ease (subjective survey) and NPS per locale.
Legal validation by region (compliance checklist).


17) Antipatterns

Concatenation of strings in code ("You won" + amount + "!") - breaks grammar.
Text in images/icons without local versions.
Hard widths for English.
Substitution of country law with language (use 'es-ES' for Mexico).
HTML translation from CMS without sanitation.
The same key with different meanings in different places.


18) QA checklist

Lines and keys

  • Named placeholders; no concatenation.
  • ICU-pluralization/genus where needed.
  • The folback chain works.

Layout and availability

  • Margin of width + 30-40%; 'line-clamp', word wrapping.
  • Alt/aria labels are localized.
  • RTL mirrors icons/navigation; numbers are readable.

Formats

  • Dates/Currencies via'Intl. '; amounts from minor units.
  • Address/Phone/Name - Flexible Country Rules.

Safety/performance

  • Translations do not execute HTML; XSS excluded.
  • Lazy chunks, CDN cache, without unnecessary rerenders.

iGaming-specifics

  • Disclaimers/18 +/help lines - by jurisdiction.
  • KYC/AML texts are legally reconciled.
  • Payment names/ETAs/fees - local.

19) Documentation in the design system

Разделы: i18n Tokens, Guides (ICU/Plural/RTL), Patterns (Emails/SMS/Toasts), Legal Strings per Region.
Tools: pseudolocal, screenshot of screens, coverage report, key linter.
Process: glossary, Translation Memory, contextual screenshots, review by a native speaker.


Brief summary

Multilingual UI is a systematic work at the level of architecture, design, content and law. Organize keys and folbacks, use ICU and 'Intl', support RTL, run a pseudo-locale in advance and ensure the legal correctness of regional wording. Then the product will feel native - from coefficients and payments to letters and help - in each country and for each user.

Contact

Get in Touch

Reach out with any questions or support needs.We are always ready to help!

Start Integration

Email is required. Telegram or WhatsApp — optional.

Your Name optional
Email optional
Subject optional
Message optional
Telegram optional
@
If you include Telegram — we will reply there as well, in addition to Email.
WhatsApp optional
Format: +country code and number (e.g., +380XXXXXXXXX).

By clicking this button, you agree to data processing.