Skip to content

Localization

Framework-agnostic i18n in a few hundred lines of TypeScript. Translation dictionaries, placeholder interpolation, count-based plural rules, locale-switching events — all from one core. Works in Node, browser, with React, Vue, Svelte, vanilla JS. For React JSX placeholders (<strong> as a translation value), pair with @mongez/react-localization.

Highlighted features

Per-locale dictionaries

extend(“en”, {…}), extend(“ar”, {…}) — flat or nested keyword maps, registered any time. Switch with setCurrentLocaleCode.

Placeholder interpolation

trans(“greet”, { name: “Ada” }) with default :name pattern, or a custom regex via configuration. Pluggable converter for non-string output.

Count-based plurals

Custom countRules pick from key_zero, key_one, key_many when a count placeholder is present. Locale-specific rules supported.

Fallback chain

Missing in current locale → look in fallback locale → return keyword itself. Inline-object form returns the object on full miss so consumers can detect it.

Locale-switching events

localizationEvents.onChange(cb) fires when the current locale flips — drive re-renders, persist the choice, update an HTML lang attribute.

Install

Terminal window
npm install @mongez/localization

@mongez/events and @mongez/reinforcements install automatically as runtime deps.

Quick peek

import { setLocalizationConfigurations, extend, trans, setCurrentLocaleCode } from "@mongez/localization";
setLocalizationConfigurations({ defaultLocaleCode: "en", fallback: "en" });
extend("en", { home: "Home", greet: "Hello :name" });
extend("ar", { home: "الرئيسية", greet: "مرحبا :name" });
trans("home"); // "Home"
trans("greet", { name: "Ada" }); // "Hello Ada"
setCurrentLocaleCode("ar");
trans("home"); // "الرئيسية"

Configure once at boot, register dictionaries per locale, read by keyword. Switching the current locale flips every subsequent trans() call.

Mental model

ConceptMental model
Translation dictionary{ [locale]: Keywords }. Keywords may nest.
KeywordIdentifier you ask for at runtime. May use dot-notation to read nested groups.
Translatablestring or { [locale]: string }. The object form is for inline per-feature translations.
ConverterFunction that interpolates placeholder values. Default plainConverter; React uses jsxConverter.
Placeholder patternRegex matched inside translation strings. Default :name.
Count rule(n: number) => boolean. Picks one of several key_<rule> translations for a { count } placeholder.

The fallback chain

When trans(keyword) runs:

  1. Look up keyword in the current locale.
  2. If missing, look in the fallback locale.
  3. If still missing, return the keyword itself.

For the inline-object form (trans({ en: "Home", ar: "..." })), step 1 reads obj[currentLocale], step 2 reads obj[fallbackLocale], step 3 returns the object unchanged so consumers can detect the miss.

Scope boundaries

ConcernLives inWhy
JSX placeholders (<strong> as a value)@mongez/react-localizationKeep the core framework-agnostic
React hooks for re-rendering on locale change(not provided)Use localizationEvents.onChange to drive a re-render via local state
Persisting the selected locale(not provided)Bring your own — varies per framework
ICU MessageFormat / nested message syntax(not provided)Out of scope — this package is name → string + placeholders

Where to go next