i18n Configuration Setup

Core Configuration (src/i18n.ts)

Initialization Steps

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

import en from './locales/en.json';
import de from './locales/de.json';
import helpEn from './locales/help_en.json';
import helpDe from './locales/help_de.json';

// 1. Define resources
const resources = {
  en: {
    translation: en,
    help: helpEn,
  },
  de: {
    translation: de,
    help: helpDe,
  },
};

// 2. Initialize i18next
i18next
  .use(LanguageDetector)
  .use(initReactI18next)
  .init({
    resources,
    fallbackLng: 'en',
    ns: ['translation', 'help'],
    defaultNS: 'translation',
    interpolation: {
      escapeValue: false,
    },
    debug: false,
  });

export default i18next;

Language Detection Configuration

Detection Order

const detectionOptions = {
  order: ['localStorage', 'navigator'],
  caches: ['localStorage'],
};

Priority:

  1. localStorage - User's previous choice (persisted)
  2. navigator.language - Browser's language setting
  3. fallbackLng: 'en' - Final fallback to English

How It Works

Application Start
    ↓
LanguageDetector checks:
  1. localStorage['i18nextLng']?
     Yes β†’ Use saved language
     No β†’ Continue to step 2
  2. navigator.language?
     'de-DE' β†’ Extract 'de'
     'en-US' β†’ Extract 'en'
     No β†’ Continue to step 3
  3. fallbackLng
     Use 'en'
    ↓
i18next initialized with selected language
    ↓
Components render with correct translations

Resources Organization

File Structure

src/locales/
β”œβ”€β”€ en.json              # English UI translations
β”œβ”€β”€ de.json              # German UI translations
β”œβ”€β”€ help_en.json         # English help content
└── help_de.json         # German help content

Namespace Configuration

ns: ['translation', 'help']
defaultNS: 'translation'

This creates two namespaces:

  • translation (default) - General app UI
  • help - Help modal content

Loading Translations

// Access translation namespace (default)
const { t } = useTranslation();
t('login.title')  // Looks in 'translation' namespace

// Access help namespace explicitly
const { t: tHelp } = useTranslation('help');
tHelp('topics.search.title')  // Looks in 'help' namespace

// Or use namespace in key
const { t } = useTranslation();
t('help:topics.search.title')  // Explicitly specify 'help' namespace

Configuration Options

i18next.init() Options

{
  // Resources
  resources: {
    en: { translation: {...}, help: {...} },
    de: { translation: {...}, help: {...} }
  },

  // Language settings
  fallbackLng: 'en',              // Final fallback
  supportedLngs: ['en', 'de'],    // Whitelist

  // Namespace settings
  ns: ['translation', 'help'],    // Available namespaces
  defaultNS: 'translation',       // Default namespace
  
  // Language detector settings
  detection: {
    order: ['localStorage', 'navigator'],
    caches: ['localStorage']
  },

  // Interpolation
  interpolation: {
    escapeValue: false             // React handles escaping
  },

  // Debug
  debug: false                     // Set true for debugging
}

Using i18n in App.tsx

import i18n from './i18n';
import { I18nextProvider } from 'react-i18next';

function App() {
  return (
    <I18nextProvider i18n={i18n}>
      <BrowserRouter>
        <div className="app">
          <Header />
          <Routes>
            {/* Routes */}
          </Routes>
        </div>
      </BrowserRouter>
    </I18nextProvider>
  );
}

export default App;

Language Persistence

Automatic Saving

When user changes language:

const { i18n } = useTranslation();

// User clicks German button
i18n.changeLanguage('de');

// Automatically saved to localStorage
// localStorage['i18nextLng'] = 'de'

Next Session

On page reload:
  1. LanguageDetector checks localStorage
  2. Finds 'de'
  3. Loads German translations
  4. All content displays in German

Debug Mode

Enable Debugging

// In src/i18n.ts
.init({
  debug: true,  // Enable console logs
  // ...
})

Console Output:

i18next: initialized with language en
i18next: loaded namespace translation
i18next: loaded namespace help
i18next: changing language to de
i18next: loaded namespace translation de

Verify Translation Loading

import i18n from '@/i18n';

// Check loaded languages
console.log(i18n.language);        // Current language
console.log(i18n.languages);       // All available languages
console.log(i18n.ns);              // All namespaces

// Get specific translation
console.log(i18n.t('login.title')); // Get translation directly

Common Configuration Patterns

Development vs Production

// Development (debug enabled)
const isDev = process.env.NODE_ENV === 'development';

.init({
  debug: isDev,
  fallbackLng: 'en',
  // ...
})

Adding New Language

  1. Add language code to supportedLngs:
supportedLngs: ['en', 'de', 'fr'],
  1. Add resources:
const resources = {
  en: { translation: en, help: helpEn },
  de: { translation: de, help: helpDe },
  fr: { translation: fr, help: helpFr },  // New
};
  1. Create translation files:
  • src/locales/fr.json
  • src/locales/help_fr.json


Last Updated: November 2025