Файлы сообщений
Один плоский или вложенный JSON-объект на неймспейс, один файл на локаль. Ключи вида namespace:dot.path; вложенные объекты разворачиваются в dot-путь.
Раскладка и ключи #
src/lib/messages/<locale>/<namespace>.json. { "nav": { "home": "Главная" } } становится t('common:nav.home').
{ "nav": { "home": "Home" } }
t('common:nav.home') // → "Home"Параметры #
{$name} подставляет значение, переданное вторым аргументом в t.
// message
{ "greeting": "Hello, {$name}!" }
t('home:greeting', { name: 'Kat' }) // → "Hello, Kat!"Множественное число и селекторы #
MF2-конструкция .match выбирает ветку по значению — категории множественного числа, а не только one/other, и они берутся из правил самой локали, а не из библиотеки.
{
"items": ".input {$count :number}\n.match $count\none {{{$count} item}}\n* {{{$count} items}}"
}1 штука · 3 штуки · 5 штук
Числа, даты и деньги #
Форматирование — это Intl под синтаксисом MF2: одно и то же сообщение выводит €1,234.50 по-английски и 1.234,50 € по-немецки без единой строчки кода, зависящей от локали. В каждом сообщении доступны :number, :integer, :offset, :string (обязательные по спецификации), а также :currency, :date, :datetime, :time, :percent, :unit (черновые).
{
"price": "Total: {$amount :currency currency=EUR}",
"due": "Due {$when :date length=long}"
}Итого: 1 234,50 € · Срок: 30 сентября 2026 г.
Когда сообщение сломано #
Ничего не бросает исключение. Исходник, который не компилируется, рендерится как собственный ключ; отсутствующий параметр оставляет фолбэк-текст MF2. Ключ, которого нет в активной локали, идёт по цепочке: сначала одноязычные соседи, потом defaultLocale, потом сам ключ.
createDialect({
defaultLocale: 'en',
onError: (error, { key, locale }) => report(error, { key, locale })
});