Skip to content
react5comPublic

About

Internationalization and translation library.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

@react5/i18n

Small, framework-free localization utilities for TypeScript/JavaScript apps and component libraries.

  • formatMessage — ICU MessageFormat (plurals, ordinals, selects) via intl-messageformat.
  • resolveMessages — pick a message group by locale, with per-message fallback and overrides.
  • createI18nStore — current locale plus change subscriptions.
  • languageOf — map a BCP 47 tag (fr-CA, fr_CA) to one of your supported languages.
  • firstDayOfWeek — locale-aware first day of the week.
  • negotiateLocale, isValidTimeZone, isValidLocaleTag — pick a supported language from navigator.languages; validate stored preferences.
  • formatDate, formatDateTime, formatHours, compareText, formatLocale — locale-aware Intl wrappers (date-only YYYY-MM-DD strings are never shifted by the time zone; invalid dates format as an empty string).
  • i18n-validate — CLI that checks translation JSON files against the English catalog.

Install

npm install @react5/i18n

Usage

import { createI18nStore, formatMessage, languageOf, resolveMessages } from '@react5/i18n'

const MESSAGES = {
  en: { tasks: '{count, plural, one {# task} other {# tasks}}', close: 'Close' },
  fr: { tasks: '{count, plural, one {# tâche} other {# tâches}}', close: 'Fermer' },
}

const i18n = createI18nStore('fr-CA')
i18n.subscribe((locale) => console.log('locale changed to', locale))

const messages = i18n.resolve(MESSAGES, { close: 'Annuler' }) // overrides win
formatMessage(messages.tasks, { count: 2 }, i18n.locale) // "2 tâches"

languageOf('de-AT', ['en', 'fr']) // "en" (first entry is the default fallback)

resolveMessages(locale, dictionaries, overrides?, fallback = 'en', options?)

dictionaries is keyed by language. A message missing from the selected language falls back to the fallback dictionary (which must exist and defines the full set of keys). overrides for keys the dictionaries don't define are passed through to the result. Pass { warnOnMissing: true } as options to log missing messages with console.warn; the library never reads the bundler environment, so the host decides, e.g. createI18nStore('en', { warnOnMissing: import.meta.env.DEV }) (the store applies its options to every resolve call). It also warns once when the locale's language has no dictionary at all. The store additionally accepts fallback in its options (createI18nStore('de', { fallback: 'fr' })) to change the fallback language.

formatMessage(template, values?, locale = 'en')

Throws on missing arguments or malformed ICU instead of silently rendering partial text.

Validating translations

Keep one JSON file per language in a directory (default src/locales), with en.json as the reference. Nested objects are message groups.

{ "scripts": { "check:translations": "i18n-validate" } }
npx i18n-validate [directory]

It fails when a file has missing or extra keys, empty messages, invalid ICU syntax, or placeholders that differ from English (plural branches may differ per language).

License

MIT

About

Internationalization and translation library.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages