Skip to content
Orbix ASP.NET Core · Tailwind CSS v1.0.2

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/Orbix/Locales/<code>.json with flat keys: "common.actions.save": "Save". They are embedded in the app and read through a standard IStringLocalizer (Infrastructure/Localization).
  • Razor views print them with @L["common.actions.save"] (L is injected by Pages/_ViewImports.cshtml; in C# code inject IStringLocalizer<SharedResource>).
  • The same files feed the in-page translator (i18next, bundled by Vite), so the language menu translates the page instantly, without a reload. Elements carry the key in data-i18n (text) or data-i18n-attr (attributes):
<button type="button" class="fd-btn fd-btn--primary">
  <span class="fd-btn__label" data-i18n="common.actions.save">@L["common.actions.save"]</span>
</button>
<input class="fd-input" type="search" placeholder="@L["common.actions.search"]" data-i18n-attr="placeholder:common.actions.search">
  • The language of a request comes from ASP.NET Core request localization: ?lang=es (demo links), then the culture cookie, then Orbix:DefaultLocale. The server renders <html lang dir>, the titles and the texts in that language.
  • The language menu saves the choice in the culture cookie (POST /locale), so the next page is rendered in the same language. GET /locale/{code} works without JavaScript.

Razor encodes every text once, so a translation can contain &, < or quotes safely.

Placeholders and plurals

Placeholders use {{name}}: "greeting": "Welcome back, {{name}}", rendered with L.Text():

@L.Text("greeting", new { name = user.Name })

Plurals use _one / _other keys (Arabic also _zero, _two, _few, _many); L.Text() picks the form of the current language from count:

"tasks.count_one": "{{count}} task",
"tasks.count_other": "{{count}} tasks"
@L.Text("tasks.count", new { count = tasks.Count })

Add a language

  1. Copy Locales/en.json to Locales/de.json and translate the values (keep the keys).

  2. Register it in appsettings.json:

    { "Code": "de", "Name": "Deutsch", "Dir": "ltr" }
  3. Add it to the language menus in Pages/Shared/Components/Topbar/Default.cshtml and Pages/Shared/Partials/auth/controls.cshtml (copy one of the existing entries and change data-fd-lang, lang, the label and the Site.Locale == "de" check).

  4. Add it to LANGUAGES in ClientApp/js/core/i18n.ts: ['en', 'es', 'pt', 'fr', 'ar', 'de'].

  5. Run npm run build and dotnet test – the translation tests check that every language has every key (add the new code to Site.Locales in tests/Orbix.Tests/Support.cs).

For a right-to-left language (Hebrew, Persian, Urdu) use "Dir": "rtl"; no other change is needed.

Remove a language

Delete its entry from appsettings.json, the two language menus and LANGUAGES, then delete Locales/<code>.json (and its code in tests/Orbix.Tests/Support.cs).

Translating your own texts

Never write visible text directly in a view: always use a key, so every language stays complete. The test HardcodedTextTests renders every page with a localizer that marks its texts and fails when a visible text is not translated (demo content inside data-demo elements is allowed). Keep the keys sorted by area (reports.sales.title) to find them easily.