DeveloperBreeze

Introduction: Why i18n Matters in 2025

As businesses go global, your frontend must cater to users from different regions, languages, and cultures. A well-implemented internationalization (i18n) strategy in your React app ensures:

  • Seamless language switching
  • Proper formatting of dates, numbers, and currencies
  • Better accessibility and user retention
  • Improved SEO in multilingual search queries

In this tutorial, you'll learn how to implement i18n in a scalable way using i18next, the most popular library for internationalizing React apps.


Project Setup: Start With a Large React App

If you don’t have a project yet, initialize a new one:

npx create-react-app react-i18n-demo
cd react-i18n-demo

Install the required dependencies:

npm install i18next react-i18next i18next-browser-languagedetector

Step 1: Configure i18next

Create a new file: src/i18n.js

import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import LanguageDetector from 'i18next-browser-languagedetector';

// Import translation files
import en from './locales/en.json';
import fr from './locales/fr.json';

i18n
  .use(LanguageDetector) // Detects user language
  .use(initReactI18next)
  .init({
    resources: {
      en: { translation: en },
      fr: { translation: fr },
    },
    fallbackLng: 'en',
    interpolation: {
      escapeValue: false, // React already escapes
    },
    detection: {
      order: ['localStorage', 'navigator', 'htmlTag'],
      caches: ['localStorage'],
    },
  });

export default i18n;

Step 2: Add Translation Files

Create folder structure:

/src
  /locales
    en.json
    fr.json

Example en.json:

{
  "welcome": "Welcome to our platform!",
  "language": "Language",
  "date_example": "Today's date is {{date, datetime}}",
  "price_example": "Price: {{price, currency}}"
}

Example fr.json:

{
  "welcome": "Bienvenue sur notre plateforme !",
  "language": "Langue",
  "date_example": "La date d'aujourd'hui est {{date, datetime}}",
  "price_example": "Prix : {{price, currency}}"
}

Step 3: Initialize i18n in Your App

Edit src/index.js:

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import './i18n'; // πŸ‘ˆ import i18n config

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);

Step 4: Using Translations in Components

Use the useTranslation hook:

import React from 'react';
import { useTranslation } from 'react-i18next';

const Home = () => {
  const { t, i18n } = useTranslation();

  const changeLanguage = (lng) => {
    i18n.changeLanguage(lng);
  };

  const today = new Date();
  const price = 199.99;

  return (
    <div className="p-4">
      <h1>{t('welcome')}</h1>

      <div className="mt-4">
        <strong>{t('language')}:</strong>
        <button onClick={() => changeLanguage('en')} className="ml-2">EN</button>
        <button onClick={() => changeLanguage('fr')} className="ml-2">FR</button>
      </div>

      <p>{t('date_example', { date: today })}</p>
      <p>{t('price_example', { price })}</p>
    </div>
  );
};

export default Home;

Step 5: Format Dates & Numbers Globally (i18next Format)

Install i18next-format plugin (optional):

npm install i18next-icu

Update i18n.js:

import ICU from 'i18next-icu';

i18n
  .use(ICU) // Enables datetime and currency formatting
  .use(LanguageDetector)
  .use(initReactI18next)
  .init({
    ...
    interpolation: {
      format: (value, format, lng) => {
        if (format === 'datetime') {
          return new Intl.DateTimeFormat(lng).format(value);
        }
        if (format === 'currency') {
          return new Intl.NumberFormat(lng, {
            style: 'currency',
            currency: lng === 'fr' ? 'EUR' : 'USD',
          }).format(value);
        }
        return value;
      },
    }
  });

Step 6: Organize Translations by Module

In large apps, structure your translation files modularly:

/locales
  /en
    home.json
    dashboard.json
  /fr
    home.json
    dashboard.json

Then load them like:

resources: {
  en: {
    home: require('./locales/en/home.json'),
    dashboard: require('./locales/en/dashboard.json'),
  },
  fr: {
    home: require('./locales/fr/home.json'),
    dashboard: require('./locales/fr/dashboard.json'),
  },
},
ns: ['home', 'dashboard'],
defaultNS: 'home',

In component:

const { t } = useTranslation('dashboard');

Step 7: SEO & Accessibility Considerations (2025)

  • βœ… Add lang attribute dynamically to <html lang="...">
  • βœ… Use language subpaths (e.g., /en/home, /fr/home) for SEO indexing
  • βœ… Translate all visible UI, not just text
  • βœ… Localize URLs and metadata (title, description)
  • βœ… Use hreflang tags in SSR setups (Next.js, Remix)

Step 8: Bonus – Persist Language Selection

Use localStorage via i18next-browser-languagedetector:

detection: {
  order: ['localStorage', 'navigator', 'htmlTag'],
  caches: ['localStorage'],
}

This saves the user's preferred language so it's remembered on the next visit.


Conclusion: Build Multilingual-Ready React Apps for 2025 and Beyond

Implementing i18n is no longer optional β€” it's essential in 2025 as user bases go global and inclusive design becomes the standard.

With i18next and react-i18next, you can:

  • Translate your app without performance loss
  • Format dates, numbers, currencies natively
  • Scale your translations across large React apps

βœ… Next Steps

  • Add RTL (right-to-left) support for Arabic or Hebrew
  • Integrate with translation platforms like Locize or Crowdin
  • Explore SSR-ready i18n setups (e.g., with Next.js)
  • Use useContext for localized theme changes (e.g., cultural preferences)

Further Reading

Continue Reading

Handpicked posts just for you β€” based on your current read.

Discussion 0

Please sign in to join the discussion.

No comments yet. Start the discussion!