# React

Source: https://rerune.io/docs/react

Set up the ReRune React SDK to add OTA delivery to an i18next app while keeping native resources, translation hooks, and language switching.

Package: @rerune/react 1.9.0. Requirements: React 18+, i18next 23.2.3+, react-i18next 14+. Overview: https://rerune.io/react-localization

## Install the package

Source: https://rerune.io/docs/react#install

Terminal:

```
npm install @rerune/react@1.9.0 i18next react-i18next
```

These 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.

> **Before you upgrade:** SDK 1.9.0 has breaking changes. In React and React Native, ReRune.setup returns the client synchronously: remove await, and await client.ready only where native initialization is asynchronous. In Angular, ReRune.provide is now ReRune.setup and must be registered at the application root. React Native apps install @react-native-async-storage/async-storage themselves. A key missing from the user's language now falls back to your i18next fallbackLng (Angular: the engine's fallback language) instead of the dashboard main language. The default request timeout is 15 seconds. Apps on ^1.8.0 receive 1.9.0 automatically, so pin ~1.8.0 until you migrate. As before, if one published translation does not fit the text built into your app, the SDK skips that whole language update and keeps showing the previous one. Translations are downloaded from https://cdn.rerune.io; if your site uses a Content Security Policy or a network allowlist, allow that address. Translations with placeholders do not work with i18next ICU plugins.

## Keep your native configuration

Source: https://rerune.io/docs/react#native-options

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 InitOptions
```

Use 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

Source: https://rerune.io/docs/react#setup

TypeScript · module scope:

```
import { ReRune } from '@rerune/react'

const client = ReRune.setup({
  otaPublishId: '<READ_ONLY_OTA_PUBLISH_ID>',
}, nativeOptions)
```

Keep imports at module scope. ReRune.setup returns the client synchronously, so call it once at module scope, or in a useState initializer in a Next.js App Router Client Component. If native initialization is asynchronous, for example with a backend loader, await client.ready where you previously awaited i18n.init. Setup reads no storage and sends no requests. 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. Rendering ReRuneProvider starts ReRune: after its first commit it restores cached translations and checks for updates. Without it, no cached or OTA text loads.

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

Source: https://rerune.io/docs/react#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. A backend loader or an asynchronous language detector makes native initialization asynchronous: setup still returns at once, so await client.ready where you awaited i18n.init.

TypeScript · supply your app-owned instance:

```
import { ReRune } from '@rerune/react'

const client = ReRune.setup({
  i18n,
  otaPublishId: '<READ_ONLY_OTA_PUBLISH_ID>',
}, nativeOptions)
```

For an already initialized instance, or one whose initialization is still running, use the attachment form documented by the package and omit the second setup argument. Passing native options to an initialized instance throws.

## SSR, hydration, and offline startup

Source: https://rerune.io/docs/react#ssr-offline

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. In the Next.js App Router, create the client with useState(() => ReRune.setup(...)) in a 'use client' module that renders ReRuneProvider, and import @rerune/react only from 'use client' modules.

Setup returns before any cache restore or OTA request. In the browser, ReRuneProvider restores the cache after its first commit, so a returning user can briefly see bundled text first. First-run offline rendering needs bundled resources. Later cached content depends on retained storage, and a dashboard-only language works offline only after the app showed it once while online. Use hydrationReady where the package requires deferred hydration.

- [Preview drafts with OTA staging](https://rerune.io/docs/staging#sdk-setup)

- [React package reference and SSR setup](https://www.npmjs.com/package/@rerune/react)
- [Runnable React example](https://github.com/BasalBit/rerune-web-examples/tree/main/examples/react-web-vite)

- See also: [Publishing and OTA delivery](https://rerune.io/docs/publishing)
- See also: [Troubleshooting](https://rerune.io/docs/troubleshooting)

---

Part of the ReRune documentation (https://rerune.io/docs). Every chapter with a summary: https://rerune.io/llms.txt. Every chapter in one file: https://rerune.io/llms-full.txt. ReRune is not Rerun (rerun.io), the robotics data visualization tool.
