Overview
React + Next.js i18n runtime SDK for the api18n translation manager.
@api18n/react is the runtime layer of api18n. It reads the JSON files
the CLI pulled into your repo and renders translated strings in your app
— with ICU plurals, date / number formatting, rich tag interpolation, and
fully typed t() calls.
What it does
- Renders translations with
useTranslations()in client components andgetTranslations()in server components. - Switches locales via
setLocale()— a plain function callable from anywhere (event handlers, route guards, even outside React). - Parses ICU MessageFormat at runtime: plurals, selects, dates, numbers, and rich tags map directly to React components.
- Types every key via the
messages.d.tsthe CLI generates. Wrong key, missing arg, wrong arg type — all fail TypeScript.
What it doesn't do
- No Provider in your JSX. Init is a side-effect import; components
just call
useTranslations(). The singleton handles state viauseSyncExternalStoreunder the hood. - No automatic locale detection. The SDK doesn't read cookies or
Accept-Languageheaders on its own. For Next.js App Router, use thedetectLocalehelper in@api18n/react/nextand wire it through your middleware. - No translation fetching at runtime. The SDK reads the JSON your CLI already pulled — no network requests, no hydration delays.
Why singleton (no Provider)
Most React i18n libraries ask you to wrap your app in a <Provider> and
prop-drill locale through context. Modern apps with deep server / client
component trees make this awkward. Singleton state with
useSyncExternalStore is:
- Less boilerplate. One init file, side-effect import, done.
- Faster re-renders. Only components that actually called
useTranslations()re-render onsetLocale— not the whole tree. - Server-safe. The
/serverentry uses React'scache()so per-request locale doesn't leak between concurrent requests.
Quickstart
// src/api18n.ts
import { createApi18n } from '@api18n/react';
import en from './messages/en.json';
import ptBR from './messages/pt-BR.json';
export const api18n = createApi18n({
resources: { en, 'pt-BR': ptBR },
defaultLocale: 'en',
});// src/main.tsx (Vite/CRA) — or app/layout.tsx (Next.js)
import './api18n';
import { App } from './App';import { useTranslations } from '@api18n/react';
export function Home() {
const t = useTranslations();
return <h1>{t('welcome', { name: 'Eduardo' })}</h1>;
}That's the whole client-side surface. For Server Components, swap
useTranslations for getTranslations from @api18n/react/server —
walked through in Examples.
Next steps
- Install the SDK: Installation
- Browse every export: API reference
- Recipes (plurals, rich tags, Server Components): Examples