Internationalisation
English and Arabic with full RTL, a two-layer translation model, and translatable schema-driven labels.
Thunder UI ships with en and ar, including full right-to-left support. Detection order is localStorage (key i18nextLng), then the browser's language, falling back to en.
Two Layers, Merged
src/i18n.ts merges core's translations with yours:
translation: { ...coreTranslations, ...appTranslations }| Directory | Owner | Behaviour |
|---|---|---|
src/core/locals/{en,ar}/ | Core | Thunder UI's own strings (227 keys). Replaced on sync, so translation fixes arrive with updates. |
src/locals/{en,ar}/ | You | Starts empty. Merged last. |
Because the app layer merges last, redefining a key in src/locals/ overrides the core string. That is the supported way to reword Thunder UI's own text - never by editing src/core/locals/.
Want to rename "Notifications" to "Alerts" across the app? Add that key to src/locals/en/ with your wording. The next --forceSync keeps your override intact.
Schema-Driven Labels Are Translatable Too
Generated form labels go through t() as well: a field's label - or its name when there is no label - is looked up in the translation tables. So module and field names become translatable by adding those keys to src/locals/.
The same is true of validation messages, which buildRules(field, t) passes through t(). See Schema to Form Fields.
RTL
Direction is applied before first paint by an inline script in index.html, alongside the theme - so switching to Arabic does not flash a left-to-right frame first.
Use CSS logical properties (border-e, ms-*, pe-*) in your own components so they mirror correctly in both directions; the core layouts already do.
Arabic text resolves to the bundled Cairo font automatically through unicode-range - see Layouts & Theming.