IntlPull
Tutorial
10 min read

How to Localize a React App: Step-by-Step Guide (2026)

Learn how to add localization to your React application with react-i18next in 2026. Complete step-by-step tutorial with code examples.

IntlPull Team
IntlPull Team
03 Feb 2026, 11:44 AM [PST]
On this page
Summary

Learn how to add localization to your React application with react-i18next in 2026. Complete step-by-step tutorial with code examples.

Quick Answer

To localize a React app:

  1. Install react-i18next: npm install react-i18next i18next
  2. Create translation JSON files for each language
  3. Configure i18next with your translations
  4. Use the useTranslation hook in components
  5. Add a language switcher

Prerequisites

  • React 16.8+ (for hooks)
  • Node.js 14+
  • Basic React knowledge

Step 1: Install Dependencies

Terminal
npm install react-i18next i18next i18next-browser-languagedetector
PackagePurpose
react-i18nextReact bindings for i18next
i18nextCore internationalization framework
i18next-browser-languagedetectorAuto-detect user's language

Step 2: Create Translation Files

Create a locales folder with JSON files for each language:

src/
  locales/
    en/
      translation.json
    es/
      translation.json
    fr/
      translation.json

src/locales/en/translation.json:

JSON
1{
2  "welcome": {
3    "title": "Welcome to Our App",
4    "subtitle": "The best solution for your needs"
5  },
6  "nav": {
7    "home": "Home",
8    "about": "About",
9    "contact": "Contact"
10  },
11  "auth": {
12    "login": "Log In",
13    "signup": "Sign Up",
14    "logout": "Log Out"
15  }
16}

src/locales/es/translation.json:

JSON
1{
2  "welcome": {
3    "title": "Bienvenido a Nuestra App",
4    "subtitle": "La mejor solucion para tus necesidades"
5  },
6  "nav": {
7    "home": "Inicio",
8    "about": "Acerca de",
9    "contact": "Contacto"
10  },
11  "auth": {
12    "login": "Iniciar Sesion",
13    "signup": "Registrarse",
14    "logout": "Cerrar Sesion"
15  }
16}

Step 3: Configure i18next

Create src/i18n.js:

JavaScript
1import i18n from 'i18next';
2import { initReactI18next } from 'react-i18next';
3import LanguageDetector from 'i18next-browser-languagedetector';
4
5import enTranslation from './locales/en/translation.json';
6import esTranslation from './locales/es/translation.json';
7import frTranslation from './locales/fr/translation.json';
8
9i18n
10  .use(LanguageDetector)
11  .use(initReactI18next)
12  .init({
13    resources: {
14      en: { translation: enTranslation },
15      es: { translation: esTranslation },
16      fr: { translation: frTranslation },
17    },
18    fallbackLng: 'en',
19    interpolation: {
20      escapeValue: false, // React already escapes
21    },
22  });
23
24export default i18n;

Step 4: Import in App Entry

src/index.js:

JavaScript
1import React from 'react';
2import ReactDOM from 'react-dom/client';
3import './i18n'; // Import i18n configuration
4import App from './App';
5
6const root = ReactDOM.createRoot(document.getElementById('root'));
7root.render(
8  <React.StrictMode>
9    <App />
10  </React.StrictMode>
11);

Step 5: Use Translations in Components

src/App.js:

JSX
1import { useTranslation } from 'react-i18next';
2
3function App() {
4  const { t } = useTranslation();
5
6  return (
7    <div>
8      <nav>
9        <a href="/">{t('nav.home')}</a>
10        <a href="/about">{t('nav.about')}</a>
11        <a href="/contact">{t('nav.contact')}</a>
12      </nav>
13
14      <main>
15        <h1>{t('welcome.title')}</h1>
16        <p>{t('welcome.subtitle')}</p>
17      </main>
18
19      <button>{t('auth.login')}</button>
20    </div>
21  );
22}
23
24export default App;

Step 6: Add Language Switcher

JSX
1import { useTranslation } from 'react-i18next';
2
3function LanguageSwitcher() {
4  const { i18n } = useTranslation();
5
6  const changeLanguage = (lng) => {
7    i18n.changeLanguage(lng);
8  };
9
10  return (
11    <div>
12      <button onClick={() => changeLanguage('en')}>English</button>
13      <button onClick={() => changeLanguage('es')}>Espanol</button>
14      <button onClick={() => changeLanguage('fr')}>Francais</button>
15    </div>
16  );
17}
18
19export default LanguageSwitcher;

Advanced Features

Variables/Interpolation

Translation:

JSON
{
  "greeting": "Hello, {{name}}!"
}

Component:

JSX
t('greeting', { name: 'John' }) // "Hello, John!"

Pluralization

Translation:

JSON
1{
2  "items": "{{count}} item",
3  "items_plural": "{{count}} items"
4}

Component:

JSX
t('items', { count: 1 }) // "1 item"
t('items', { count: 5 }) // "5 items"

Nested Keys

JSX
// Access nested keys with dot notation
t('welcome.title')
t('nav.home')

Trans Component (JSX in translations)

Translation:

JSON
{
  "terms": "I agree to the <link>Terms of Service</link>"
}

Component:

JSX
1import { Trans } from 'react-i18next';
2
3<Trans i18nKey="terms" components={{ link: <a href="/terms" /> }}>
4  I agree to the <a href="/terms">Terms of Service</a>
5</Trans>

Managing Translations at Scale

As your app grows, managing JSON files becomes difficult:

  • Multiple developers editing same files
  • No translation memory
  • Hard to track missing translations
  • Manual export/import with translators

Solution: Use a Translation Management System

IntlPull automates React localization:

Terminal
1# Pull latest translations
2npx @intlpullhq/cli download --output ./src/locales
3
4# Push new strings
5npx @intlpullhq/cli upload
6
7# Check translation status
8npx @intlpullhq/cli status

Benefits:

  • AI-powered translation
  • Collaboration with translators
  • Translation memory
  • Automatic sync with your repo

Common Issues and Solutions

Issue: Translations not updating

Solution: Make sure you imported i18n before App:

JavaScript
import './i18n';
import App from './App';

Issue: Blank content on first load

Solution: Add Suspense fallback:

JSX
1import { Suspense } from 'react';
2
3<Suspense fallback="Loading...">
4  <App />
5</Suspense>

Issue: TypeScript errors

Solution: Install types and configure:

Terminal
npm install --save-dev @types/react-i18next

Best Practices

  1. Use namespaces for large apps to organize translations
  2. Keep keys semantic (e.g., auth.login not button1)
  3. Don't concatenate strings - use interpolation
  4. Test with pseudo-localization before real translations
  5. Use a TMS like IntlPull for collaboration

Frequently Asked Questions

How do I add a new language?

  1. Create a new JSON file (e.g., locales/de/translation.json)
  2. Add it to i18n config resources
  3. Add button to language switcher

How do I handle RTL languages?

Add dir attribute based on language:

JSX
<html dir={i18n.language === 'ar' ? 'rtl' : 'ltr'}>

How do I lazy-load translations?

Use i18next-http-backend:

JavaScript
1import Backend from 'i18next-http-backend';
2
3i18n.use(Backend).init({
4  backend: {
5    loadPath: '/locales/{{lng}}/{{ns}}.json',
6  },
7});

Summary

To localize a React app:

  1. Install react-i18next and i18next
  2. Create translation JSON files
  3. Configure i18next
  4. Use useTranslation hook
  5. Add language switcher
  6. Use a TMS for scale

Ready to scale your localization? IntlPull automates React i18n with AI translation and seamless CLI integration.

Tags
react
localization
tutorial
react-i18next
how-to
2026
IntlPull Team
IntlPull Team
Engineering

Building tools to help teams ship products globally. Follow us for more insights on localization and i18n.