Adding a second language to a React app sounds like a small task until you hit plurals, dates, lazy loading and a growing pile of JSON files. react-i18next is the most widely used way to handle this, and with a sensible setup it scales from a side project to a product in twenty languages. This guide walks through a practical React i18n setup and how to keep translations flowing once the code is ready.
What Is React i18n?
React i18n means internationalizing a React application: separating user-facing text from components, loading the right language at runtime and formatting values such as dates and numbers for each locale. It is the technical groundwork that makes software localization possible. If the difference between the two terms is new to you, read internationalization vs localization first.
Why react-i18next?
react-i18next is built on i18next, a mature JavaScript translation framework. It offers React hooks, a component for translating text with embedded markup, plural and context support, namespaces for splitting large projects and plugins for language detection and loading files over HTTP. The official react-i18next documentation covers every option in detail.
Step 1: Install the Packages
Install i18next and react-i18next. Most projects also add i18next-browser-languagedetector to pick up the user's language and i18next-http-backend to load translation files on demand instead of bundling them all.
Step 2: Organize Translation Files
A common structure is one folder per language and one JSON file per namespace, for example locales/en/common.json and locales/de/common.json. Use nested, descriptive keys such as checkout.button.pay. Good keys tell translators where text appears and make missing strings easy to find.
Step 3: Initialize i18next
Create an i18n.js file that initializes i18next with the React plugin, sets a fallback language, lists supported languages and disables HTML escaping (React already escapes output). Import this file once at the root of your app, before rendering.
Step 4: Translate Components
Inside components, the useTranslation hook gives you a t function. Replace hard-coded text with keys, for example t('checkout.button.pay'). For sentences that contain links or bold text, use the Trans component so translators can move the markup to wherever the grammar of their language needs it.
Step 5: Handle Plurals, Variables and Formatting
- Interpolation. Insert values with placeholders such as
{{name}}. Never build sentences by concatenating strings, because word order changes between languages. - Plurals. i18next uses suffixes such as
_oneand_other, based on the Unicode plural rules. Languages like Polish or Arabic need more forms, which translators add in their files. - Dates and numbers. Use the built-in
Intlformatting rather than formatting values by hand. - Context. Use the context feature when the same English word needs different translations, such as "Open" as a verb or an adjective.
Step 6: Switch Languages and Lazy Load
Call i18n.changeLanguage('de') from a language switcher and store the choice. With the HTTP backend, only the active language is loaded, which keeps your bundle small as you add more locales. Wrap the app in React Suspense so components wait until translations are ready.
Common React i18n Mistakes
- Hard-coded strings left in components, especially in error messages and aria labels.
- Concatenated sentences that cannot be translated correctly.
- Layouts that break when German or Finnish text is 30% longer than English.
- Keys renamed in code without updating translations, leaving users with raw keys on screen.
- Translation files edited by hand in many places, with no single source of truth.
From Code to Translations: The Workflow
Once the code is ready, the challenge moves to keeping JSON files translated as the product changes. Developers add keys every week, and copying files to translators by email does not scale. A better setup syncs your locale files with a TMS, pre-translates new keys with translation memory and AI, sends them to reviewers and returns the results through translation automation. Our article on how to translate a JSON file covers the file-level details.
How WordBeam Helps React Teams
WordBeam imports i18next JSON files with keys intact, applies translation memory and your glossary, and pre-translates new strings with DeepL, GPT, Claude or Grok. Translators work in a CAT editor with placeholder and tag checks, and on the Studio plan GitHub and GitLab integrations keep locale files in sync. It is built for exactly this kind of UI translation.
Frequently Asked Questions
Is react-i18next the best library for React i18n?
It is the most widely used and works well for most apps. Alternatives such as react-intl (FormatJS) and LinguiJS are also solid choices, especially if you prefer ICU message syntax.
Should I bundle translations or load them over HTTP?
For a few languages, bundling is simple. As you add more, loading files on demand keeps the app fast.
How do I handle right-to-left languages?
Set the dir attribute on the document based on the active language and use CSS logical properties such as margin-inline-start so layouts mirror automatically.