@spfn/i18n supplies the small runtime between your translation catalogs and your UI: interpolation, fallback lookup, server helpers, and React context. Your application keeps ownership of the words and the locale policy.
Catalog loading, locale detection, routing, persistence, and content stay in the consuming application. The runtime accepts plain locale → namespace → message objects and turns them into predictable translators without imposing a file layout, fetch layer, or CMS.
getClientMessages() resolves selected namespaces on the server, merging fallback values first and locale-specific values second. Pass the serializable result through I18nProvider; client components call useT() without a loading flash or a second catalog request.
Locale, namespace, key, message — application-owned objects.
Translate independently of React, Next.js, or SPFN.
Named string and number placeholders remain visible when missing.
Locale-specific values override a configured fallback locale.
Configure once, then resolve namespace-scoped translators.
Serialize only selected, fully resolved namespaces.
I18nProvider, useT, and useLocale for client subtrees.
No loaders, locale detection, routing, or plural-rule policy.