@molecule/api-i18n-simple
Provider bond · i18n · API (Node) · v1.0.2 · Apache-2.0
Simple built-in i18n provider using Intl APIs
npm install @molecule/api-i18n-simplenpm · Source on GitHub · Implements @molecule/api-i18n
How it works
@molecule/api-i18n-simple is a provider bond on the API (Node) side: it implements the i18n core interface (@molecule/api-i18n) with a concrete vendor or library behind it.
Your code calls the core; you wire this provider once at startup. Swapping vendors later is one line in that wiring, not a rewrite.
import { setProvider } from '@molecule/api-i18n'
import { provider } from '@molecule/api-i18n-simple'
setProvider(provider)Works with: @molecule/api-i18n
Reference
Simple i18n provider for molecule.dev.
Auto-generated, AI-first package reference for the molecule.dev ecosystem. It is written to be read by coding agents as much as by people, and is generated from this package's source — edit
src/index.tsJSDoc, not this file.
Quick Start
import { setProvider } from '@molecule/api-i18n'
import { provider } from '@molecule/api-i18n-simple'
setProvider(provider)
Type
provider
Installation
npm install @molecule/api-i18n-simple @molecule/api-i18n
API
Functions
createSimpleI18nProvider(initialLocale, initialLocales)
Creates a simple i18n provider that implements the I18nProvider interface
using in-memory translations, Intl APIs for formatting, and CLDR plural rules.
function createSimpleI18nProvider(
initialLocale?: string,
initialLocales?: LocaleConfig[],
): I18nProvider
initialLocale— The starting locale code (default:'en').initialLocales— Pre-loaded locale configurations with translations.
Returns: An I18nProvider with translation, formatting, and pluralization support.
Constants
provider
Default simple provider.
const provider: I18nProvider
Core Interface
Implements @molecule/api-i18n interface.
Bond Wiring
Setup function to register this provider with the core interface:
import { setProvider } from '@molecule/api-i18n'
import { provider } from '@molecule/api-i18n-simple'
export function setupI18nSimple(): void {
setProvider(provider)
}
Injection Notes
Requirements
Peer dependencies:
@molecule/api-i18n^1.0.1
Runtime Dependencies
@molecule/api-i18n
This bond implements the same I18nProvider fleet contract as
@molecule/app-i18n's core simple provider and the @molecule/app-i18n-i18next
bond — cross-checked so swapping providers never silently changes behavior:
setLocale(locale)THROWSError('Locale "<code>" not found')for an unregistered locale — it never silently degrades.t(key, values, { count }): whencountis given, the plural-suffixed key (`${key}_${pluralForm}`, falling back to`${key}_other`) is tried BEFORE the basekey— matching i18next's own resolution order. A catalog with bothitemanditem_one/item_otherpluralizes.addTranslations()DEEP-merges nested translation objects; two calls sharing a top-level namespace key merge their subtrees instead of one clobbering the other.exists(key)follows the same locale-fallback chain ast()(active locale, then English) — it agrees with whethert(key)would render real text, not just whether the active locale's own catalog has it.
E2E Tests
Integration checklist — drive the real flow (no mocks), adapt each item to this app's actual localized responses/emails, and check every box off one by one. A box you can't check is an integration bug to fix — not a skip:
- A user-facing server string (an API error message, an email
subject/body, a notification) renders TRANSLATED for a non-default locale:
set the user's locale (or send Accept-Language) and confirm the
response/email comes back in that language, not English — passed per-request
as
t(key, values, { locale }), NEVER a process-globalsetLocale()per request (that races concurrent users and localizes the wrong one). - A missing/untranslated key falls back to its
defaultValue(rendered English), NOT the raw dot-notation key — a response or email showinguser.error.notFoundverbatim is exactly the bug this prevents. -
{{variable}}interpolation fills correctly — the appName/count/etc. appear in the message and no literal{{appName}}leaks through. - If the app pluralizes,
{ count }resolves the right CLDR form (one/other/…) — and ONLY with a real bonded provider (the auto fallback ignores count), so "1 item" vs "2 items" reads correctly. - The locale is derived per-request from the authenticated user's preference (or Accept-Language), so two concurrent users with different locales each get their own language — one user's locale never leaks into another's email/response.