i18n
Summary
Soma localizes its own interface strings, the 41
texts the components render themselves: the date picker's
footer buttons, presets and aria-labels, dismiss/loading
labels, the RESTful table's verbs, tree toggles, dialog and
palette chrome, the dropzone prompts, the navbar's More menu.
Month names, weekday names, and the first day of the week come
from the browser's Intl data, so
every language works there without a translation
file. 42 locale packs ship built in: every EU
official language, the Nordics, and the most-used world
languages (see the list below); anything else registers a
41-key pack.
Application text is deliberately out of scope: on
server-rendered pages that belongs to the server's own
resource bundles. The date input format also stays
ISO (YYYY-MM-DD): it's a data contract, not a
display string.
Locale selection
| Source | Notes |
|---|---|
Soma.i18n({ locale: 'cs' }) | Explicit: wins over everything. Set it before components render; strings are baked at construction and existing DOM is not re-rendered. |
<html lang="cs"> | The normal server-rendered path: the server sets one attribute and Soma follows. |
| (neither) | English. |
Locale codes are case-insensitive, and regional codes fall
back to their base language: cs-CZ uses the
cs pack (an exact regional pack, if registered,
wins), and zh-TW/zh-HK/zh-MO
resolve to Traditional Chinese. Per-key overrides win over the
active pack; anything still missing falls back to English.
Soma.i18n({ locale: null }) clears an explicit
locale and returns to <html lang> detection.
Examples
JavaScript API
| Member | Description |
|---|---|
Soma.i18n({ locale }) | Switch locale (null returns to <html lang>/English). |
Soma.i18n({ messages: {…} }) or Soma.i18n({ 'datePicker.today': '…' }) | Per-key overrides: they win over the active pack. Unknown keys throw (a typo fails loudly). messages: null clears all overrides. |
Soma.i18n.register(code, pack) | Add or extend a locale pack; merges, so partial packs are fine: missing keys fall back to English. Any BCP-47 code works, including private-use tags. |
Soma.i18n.locales() | The built-in locale codes. |
Soma.i18n() | Reads state: { locale, messages }. |
Soma.i18n({ locale: 'cs' }); // pick a built-in pack
Soma.i18n(); // → { locale, messages }
Soma.i18n({ 'datePicker.today': 'Nyní' }); // override single keys
Soma.i18n.locales(); // → the built-in locale codes
// Add a language — partial packs fall back to English per key:
Soma.i18n.register('de', {
'datePicker.today': 'Heute',
'datePicker.clear': 'Löschen',
'datePicker.chooseDate': 'Datum wählen',
'datePicker.previousMonth': 'Voriger Monat',
'datePicker.nextMonth': 'Nächster Monat',
'datePicker.hour': 'Stunde',
'datePicker.minute': 'Minute',
'toast.dismiss': 'Schließen',
'select.searchOptions': 'Optionen durchsuchen',
'select.clearSelection': 'Auswahl löschen',
'select.noMatches': 'Keine Treffer',
'restfulTable.noEntries': 'Keine Einträge',
'restfulTable.loading': 'Laden',
'sidebar.resize': 'Seitenleiste anpassen',
// …any keys you leave out stay English
});
Soma.i18n({ locale: 'de' });
Built-in locales
en (fallback catalog) plus 42 packs — every EU
official language, the Nordics, and the most-used world
languages:
One caveat: the packs are machine-translated standard UI
vocabulary
awaiting
native-speaker review. Serbian ships in Cyrillic:
register a sr-Latn pack if you prefer latinica;
no resolves to Bokmål (nb).
Right-to-left (RTL) layout
Soma fully supports RTL: set dir="rtl" on
<html> (or any subtree) and everything
mirrors: layout and components (CSS logical properties),
popover alignment, drag directions, and keyboard semantics
(horizontal arrows follow visual direction in tabs
and the date-picker grid, per ARIA practice). Combined with
the ar, fa, he, and
ur packs, those languages are supported end to
end. Try it live: the direction button in the bottom-right
corner flips this whole docs site.
String catalog
| Key | English | Czech (built in) | Used by |
|---|---|---|---|
datePicker.today | Today | Dnes | date picker |
datePicker.clear | Clear | Vymazat | date picker |
datePicker.chooseDate | Choose date | Vyberte datum | date picker (aria) |
datePicker.previousMonth / .nextMonth | Previous/Next month | Předchozí/Další měsíc | date picker (aria) |
datePicker.hour / .minute | Hour / Minute | Hodina / Minuta | date picker (aria) |
dateRange.last7 / .last30 | Last 7 days / Last 30 days | Posledních 7 dní / Posledních 30 dní | date-range presets |
dateRange.thisMonth / .lastMonth | This month / Last month | Tento měsíc / Minulý měsíc | date-range presets |
toast.dismiss | Dismiss notification | Zavřít | toasts (aria) |
banner.dismiss | Dismiss banner | Zavřít | banners (aria) |
message.dismiss | Dismiss | Zavřít | messages (aria) |
select.searchOptions | Search options | Hledat možnosti | select (aria) |
select.clearSelection | Clear selection | Vymazat výběr | select (aria) |
select.noMatches | No matches | Žádné shody | select |
combobox.noSuggestions | No suggestions | Žádné návrhy | combobox |
dropzone.browse | Drag and drop files here, or browse | Přetáhněte soubory sem, nebo procházejte | dropzone (generated prompt) |
dropzone.reject | Not accepted: {names} | Nepřijato: {names} | dropzone (alert) |
dropzone.remove | Remove {name} | Odebrat {name} | dropzone (aria) |
restfulTable.noEntries | No entries | Žádné záznamy | RESTful table |
restfulTable.loading | Loading | Načítání | RESTful table |
restfulTable.edit / .delete / .update / .add / .cancel | Edit / Delete / Update / Add / Cancel | Upravit / Smazat / Aktualizovat / Přidat / Zrušit | RESTful table |
restfulTable.operations | Operations | Akce | RESTful table (header) |
tree.expand / .collapse | Expand / Collapse | Rozbalit / Sbalit | tree (aria) |
spinner.loading | Loading | Načítání | spinner (aria) |
sidebar.resize | Resize sidebar | Změnit šířku panelu | sidebar (aria) |
navbar.more | More | Více | responsive navbar |
breadcrumbs.more | More | Více | collapsed breadcrumbs (aria) |
dialog.confirm / .cancel / .ok | Confirm / Cancel / OK | Potvrdit / Zrušit / OK | Soma.confirm / Soma.alert buttons |
palette.label | Command palette | Paleta příkazů | command palette (aria) |
palette.placeholder | Type a command… | Zadejte příkaz… | command palette |
palette.empty | No matching commands | Žádné odpovídající příkazy | command palette |
What Intl covers automatically
For the active locale the date picker derives month names,
short weekday names, and the first day of the week from
Intl.DateTimeFormat / Intl.Locale —
no dictionary involved. A per-instance
Soma.datePicker(input, { locale }) option still
overrides the global locale where needed. Locale tags
Intl rejects (e.g. private-use x-…)
fall back to English names rather than failing.
Easter eggs 🖖
To prove Soma.i18n.register() handles anything with
a BCP-47 code, this page registers three extra locales:
Klingon (tlh, a real ISO 639-2
code; vocabulary after Okrand), Sumerian
(sux, reconstructed from attested roots; the
previous/next month labels honor the Sumerian
conception that the past lies before you,
igi, and the future behind,
egir), and Hobbitish
(x-hobbit: Westron has no ISO code, so it
demonstrates a private-use BCP-47 tag; and since
Tolkien rendered Westron as English, the pack is proper
Shire-speech). Pick them at the bottom of the locale dropdown
above. None of them ship in the library bundle, and
Intl has no calendar data for them, so month names
fall back, exactly the graceful degradation a custom locale
gets. (The Shire Reckoning — Afteryule, Solmath, Rethe… — must
wait for a custom-month-names date-picker option.)