@sonenta/i18n-core
v1.4.2
Published
Framework-agnostic Sonenta i18n engine: CDN bundles, surfaces, a11y, plurals, missing-key, language catalog. Powers the @sonenta framework bindings.
Maintainers
Readme
@sonenta/i18n-core
The framework-agnostic Sonenta i18n engine. It is the
shared core under the official framework bindings — @sonenta/react-i18next,
@sonenta/vue-i18n, @sonenta/svelte-i18n, and @sonenta/next — so they all
resolve translations identically.
Most apps should install a binding (e.g.
@sonenta/react-i18next), not this package directly. Use@sonenta/i18n-coreonly to build a custom binding or to drive translations from non-UI code.
npm install @sonenta/i18n-core i18nextWhat's in the core
Everything framework-neutral, extracted from @sonenta/react-i18next (the
oracle — the core passes react-i18next's own engine test suite):
SonentaI18n— the engine: CDN bundle loading, sync offline construction frominitialBundles,start(),t(),subscribe()/getSnapshot()/refresh()(an external-store contract any framework can bind to).- Surface variants (#911) —
setSurface(), sparse{ns}.{surface}.jsonoverlays,surfaceForWidth, breakpoints. - A11y surfaces (#989) —
aria()/alt()/a11y()+ plain-language toggle; the key-type taxonomy (treatmentsFor,baseRoleFor). - Language catalog (#803) —
dir()/nativeName()/languageMeta(). - Available languages — per-version manifest.
- Missing-key streaming + gate, CLDR plurals, the on-screen key
registry (feeds
@sonenta/feedback), and the transport abstraction.
Framework-neutral by injection
The engine inits a vanilla i18next instance. A binding injects its own
i18next plugin (e.g. initReactI18next) via the constructor:
import { SonentaI18n } from "@sonenta/i18n-core";
import { initReactI18next } from "react-i18next";
// React binding:
const i18n = new SonentaI18n(config, { plugins: [initReactI18next] });
// Vanilla / Vue / Svelte: no React plugin.
const i18n = new SonentaI18n(config);
await i18n.start();
i18n.t("home.title");i18next is a peer dependency (>=23 <27) — bring your own.
fetchImpl — injecting your own fetch
start() takes the fetch the engine uses: await i18n.start(myFetch). It is
stored on the instance (src/i18n.ts:154) and resolved at call time
(:656-658), never captured at construction — so setLocale() and reload()
keep using it. That matters for an authenticated fetch: an engine that resolved
it once would silently fall back to the global fetch on the next language
change and lose the caller's auth headers with no error anywhere.
Note it is a start() argument, not a field of SonentaConfig (src/types.ts:80
declares no fetchImpl). The bindings expose it as an option of their own
setup call, which they forward to start():
@sonenta/vue-i18n (src/plugin.ts:13), @sonenta/svelte-i18n
(src/index.ts:35), @sonenta/next (src/server.ts:32), and
@sonenta/react-i18next as the fetchImpl prop of <SonentaProvider>.
It is a supported, public option — documented here because it shipped undocumented, which left callers unable to tell it apart from a private field that could be removed without notice.
License
MIT © Sonenta
