React
Add OTA delivery to an i18next app while keeping native resources, translation hooks, and language switching.
Requirements: React 18+, i18next 23+, react-i18next 14+
Package referenceOn this page
Install the package
Terminal
npm install @rerune/react@1.6.0 i18next react-i18nextThese examples follow the SDK version shown above. Start with an application that already renders local translations through i18next and react-i18next. Keep at least one bundled fallback language.
Keep your native configuration
TypeScript · existing i18next options
import type { InitOptions } from 'i18next'
import en from './locales/en/translation.json'
import de from './locales/de/translation.json'
const nativeOptions = {
lng: 'en',
fallbackLng: 'en',
ns: ['translation'],
defaultNS: 'translation',
resources: { en: { translation: en }, de: { translation: de } },
interpolation: { escapeValue: false },
} satisfies InitOptionsUse your actual locale file paths and native configuration. ReRune OTA targets the translation namespace. Other namespaces remain owned by your native i18next setup. The native options object can stay in your existing startup module.
Replace initialization and the provider
TypeScript · existing asynchronous startup
import { ReRune } from '@rerune/react'
const client = await ReRune.setup({
otaPublishId: '<READ_ONLY_OTA_PUBLISH_ID>',
}, nativeOptions)Keep imports at module scope. Run the awaited setup once in the application startup where you previously initialized i18next, then mount the app. The nativeOptions object is the configuration shown above. Replace the OTA placeholder with your project read-only Publish ID.
TSX · root provider
import { ReRuneProvider } from '@rerune/react'
<ReRuneProvider client={client} defaultNS="translation">
<App />
</ReRuneProvider>Replace I18nextProvider with ReRuneProvider and preserve your default namespace. The provider includes native i18next context. Existing translation hooks continue to use the same keys.
TSX · existing component
import { useTranslation } from 'react-i18next'
export function App() {
const { t } = useTranslation()
return <h1>{t('headline')}</h1>
}Keep plugins and an existing instance
If the app owns an i18next instance with detectors, backend loaders, or plugins, supply that instance to setup. Keep plugin registration and native settings in their existing order. External consumers can use client.i18n.
TypeScript · supply your app-owned instance
import { ReRune } from '@rerune/react'
const client = await ReRune.setup({
i18n,
otaPublishId: '<READ_ONLY_OTA_PUBLISH_ID>',
}, nativeOptions)For an already initialized instance, use the attachment form documented by the package and omit the second setup argument. Passing native options again to an initialized instance rejects.
SSR, hydration, and offline startup
Server-rendered translated HTML needs a request-local i18next instance and awaited ReRune.preload before rendering. Pass the matching hydration state to browser setup with the same locale, resources, variant, and syntax. Browser-only setup cannot change HTML or metadata already sent to a crawler.
Awaited native setup does not wait for every asynchronous cache restore or OTA request. First-run offline rendering needs bundled resources; later cached content depends on retained storage. Keep your normal loading and error behavior, and use hydrationReady where the package requires deferred hydration.