Quickstart
React + i18next
Install the SDK, wrap your app in <SonentaProvider />, and call useTranslation(). Missing keys flow to your dashboard automatically — no extra wiring.
1. Install
Single dependency. No peer-dep gymnastics — the SDK includes everything React-side.
terminal 1npm i @sonenta/react-i18next 2. Wrap your app
SonentaProvider takes a projectId and an apiKey. Everything else has sane defaults: locale auto-detect from the browser, namespaces lazy-loaded from your CDN, missing-key handler debounced and POSTed automatically.
main.tsx 1// src/main.tsx2import { SonentaProvider } from "@sonenta/react-i18next";3import { createRoot } from "react-dom/client";4import { App } from "./App"; 6createRoot(document.getElementById("root")!).render(7 <SonentaProvider8 projectUuid="proj_xxx"9 token={import.meta.env.VITE_SONENTA_TOKEN}10 defaultLocale="en"11 namespaces={["common"]}12 >13 <App />14 </SonentaProvider>15); All SonentaProvider props
| Prop | Type | Default |
|---|---|---|
| projectUuid | string | — required |
| token | string | — required |
| defaultLocale | string | browser |
| defaultNS | string | "common" |
| namespaces | string[] | ["common"] |
| cdnUrl | string | cdn.sonenta.com |
| baseUrl | string | api.sonenta.com |
| missingHandlerEndpoint | string | /v1/missing |
| debounceMs | number | 5000 |
| transport | (batch) => void | Promise<void> | internal |
3. Use the hook
useTranslation() returns { t, i18n }. Familiar shape if you've used react-i18next. i18n.ready tells you when initial namespaces have hydrated; i18n.changeLanguage() swaps locale at runtime.
Checkout.tsx 1// src/Checkout.tsx2import { useTranslation } from "@sonenta/react-i18next"; 4export function Checkout() {5 const { t, i18n } = useTranslation("common"); 7 if (!i18n.ready) return null; // first paint after hydration 9 return (10 <button onClick={() => i18n.changeLanguage("fr")}>11 {t("checkout.review.confirm")}12 </button>13 );14} What you get for free
- Missing-key capture. Any key you call that isn't in the dictionary is queued, debounced (default 5s), and POSTed to your dashboard's missing queue. Production-safe — your fallback still renders.
- CDN-served namespaces. Translation bundles are pulled from
cdn.sonenta.comwith HTTP caching and stale-while-revalidate. No build-time bundling required. - Locale auto-detect. If you don't pass
defaultLocale, the SDK readsnavigator.languageand falls back to your project's default. - Open exports. Whatever you push to Sonenta, you can export back to JSON i18next, XLIFF, or PO. Switch tools tomorrow without rewriting your code.
Custom transport (advanced)
Need to log missing keys to your own observability stack, gate them behind your auth, or stub them out in tests? Pass a transport function. The SDK still debounces and batches; you decide what happens to the batch.
main.tsx 1// custom transport — useful for tests, edge cases, or auditing2<SonentaProvider3 projectUuid="proj_xxx"4 token={import.meta.env.VITE_SONENTA_TOKEN}5 debounceMs={2000}6 transport={(batch) => fetch("/internal/i18n-misses", {7 method: "POST",8 body: JSON.stringify(batch),9 })}10/>