@gomani/i18n
v0.8.0
Published
Inclusion by default: ICU messages, locale-aware formatting, locale routing, and full RTL/bidi support.
Maintainers
Readme
@gomani/i18n
Inclusion by default (P11): ICU messages, locale-aware formatting, locale routing, and full RTL/bidi — with the active locale resolved server-side, per request, zero-JS.
Locale is a signal (like network quality in @gomani/adaptive): @gomani/server resolves it from the
request — a URL locale prefix, the gomani-locale pin cookie, Accept-Language, then the default —
before the synchronous render, so only the chosen language's strings and the correct dir reach the
HTML. No client i18n runtime, no flash of the wrong language.
import { createI18n } from '@gomani/i18n';
export const { t } = createI18n({
locales: ['en', 'sw', 'ar'],
defaultLocale: 'en',
messages: {
en: { items: '{n, plural, one {# item} other {# items}}' },
sw: { items: '{n, plural, one {kitu #} other {vitu #}}' },
ar: { items: '{n, plural, one {# عنصر} other {# عناصر}}' },
},
});
t('items', { n: 3 }); // locale-correct plural, formatted with Intl- ICU MessageFormat — arguments,
number/date/timewith styles,plural/selectordinal(offset:,=N,#),select, nesting, and apostrophe quoting. Plural/number/date selection uses the platformIntl(present everywhere, zero bytes shipped). - RTL/bidi first-class —
isRtl/directionset<html dir>;bidiIsolatewraps embedded text. - Locale routing —
parseLocalePath/localizePath/stripLocale. - Formatting —
formatNumber/formatCurrency/formatDate/formatRelativeTime/formatList. - Font-subsetting is automatic — because messages render to HTML in the active locale, the per-route subsetter ships exactly that locale's glyphs, with no configuration.
The client switch lives at @gomani/i18n/client (setLocale writes the cookie and reloads, so the
next render is fully server-decided).
