Skip to content
Orbix Angular · Bootstrap 5 v1.0.1

Languages and RTL

Orbix ships in English, Spanish, Portuguese, French and Arabic. Arabic switches the whole layout to right-to-left. Numbers, currencies and dates are formatted for the active language with the browser Intl API.

Language menu

How it works

  • Translations live in src/locales/<locale>/<area>.json (common.json, nav.json, dashboards.json...). A key is the file name plus the path inside it: common.actions.save. Each src/locales/<locale>/index.ts bundles the files of its language into one chunk.
  • The dictionaries are loaded by Transloco (@jsverse/transloco: only English and the active language, through the loader of src/core/i18n.ts), and templates read them with t(). t() reads the current language, a signal, so the language menu re-renders every template instantly, without a reload:
import { t, lang } from '@/core/i18n';
import { formatValue } from '@/core/format';

export class ReportsSalesPage {
  protected readonly t = t;
  protected readonly fmt = formatValue;
  protected readonly lang = lang;   // the active language: lang() is 'en', 'es', 'pt', 'fr' or 'ar'
}
<button type="button" class="fd-btn fd-btn--primary">
  <span class="fd-btn__label" data-i18n="common.actions.save">{{ t('common.actions.save') }}</span>
</button>
<input class="fd-input" type="search" [attr.placeholder]="t('common.actions.search')" data-i18n-attr="placeholder:common.actions.search">
<span>{{ fmt('currency', 48290.5) }}</span>   <!-- $48,290.50 · 48.290,50 US$ · ٤٨٬٢٩٠٫٥٠ US$ -->
  • The TranslocoService is available for dependency injection as usual (inject(TranslocoService)), for example for selectTranslate() streams in your services; the active language is the same.
  • The data-i18n and data-i18n-attr attributes are optional in your own components; the template keeps them so that markup created at runtime (data grids, page scripts, foundry-ui behaviors) is translated too.
  • The choice is saved in the browser (fd:lang), and demo links accept ?lang=es. Without a saved choice the template starts in English. <html lang> and dir follow the language.

Placeholders and plurals

The dictionaries keep one format in every Orbix edition (the Transloco transpiler of src/core/i18n.ts). Placeholders use double braces: "greeting": "Welcome back, {{name}}" and t('greeting', { name: user.name }).

Plurals use _one / _other keys (Arabic also _zero, _two, _few, _many, the plural categories of the language) and a count:

{ "count_one": "{{count}} task", "count_other": "{{count}} tasks" }
{{ t('tasks.count', { count: tasks().length }) }}

Formats: fmt(type, value, options) with the types number, decimal, compact, currency, currency-compact, percent, date, date-long, date-short, datetime, time, month, weekday, relative and duration-min; options { digits, currency }.

Add a language

  1. Copy src/locales/en to src/locales/de and translate the values (keep the keys and index.ts).
  2. In src/core/i18n.ts, add it to LANGUAGES (['en', 'es', 'pt', 'fr', 'ar', 'de']) and to the dictionaries map (de: () => import('../locales/de')).
  3. Add it to the language menus in src/components/shell/topbar.html and src/components/auth/controls.html (copy one of the existing entries and change data-fd-lang, lang, the aria-checked binding and the label).
  4. Add the code to the language pattern of src/boot/orbix-boot.js (/^(en|es|pt|fr|ar|de)$/).
  5. Run npm test – the translation tests check that every language has every key with the same placeholders.

For a right-to-left language (Hebrew, Persian, Urdu) nothing else is needed: the direction is derived from the language code.

Remove a language

Remove it from LANGUAGES and the dictionaries map, the two language menus and the boot pattern, then delete src/locales/<locale>/.

Translating your own texts

Never write visible text directly in a template: always use a key, so every language stays complete. The test tests/hardcoded-text.spec.ts renders every page and fails when a visible text or label is not translated (demo content inside data-demo elements is allowed). Keep your keys in their own file per area (reports.json) to find them easily.