Internationalization (i18n)
Translate UI with i18next/react-i18next, interpolate values, and handle RTL languages like Arabic.
Internationalization (i18n) is structuring an app so its UI can be translated and localized without code changes. Instead of hard-coding strings, you reference translation keys (e.g. expense.title) that resolve to the active language's strings. The de-facto standard in React is i18next with the react-i18next bindings.
You configure i18next once with a resources object holding a translation map per language, a default language (lng), and a fallbackLng. Components call the useTranslation hook to get a t() function for looking up keys, plus the i18n instance for reading and changing the current language. t() supports interpolation — t('expense.total', { amount: '₹1,200' }) fills the {{amount}} placeholder.
Beyond text, real i18n handles directionality. Right-to-left languages like Arabic require dir="rtl", which mirrors the layout. A common pattern is to set the dir attribute from the active language so the whole subtree flips automatically. Mature setups also handle pluralization, date/number/currency formatting (via the Intl API), and lazy-loading translation bundles per locale.
Translation keys are exactly Java's ResourceBundle / messages.properties files keyed by locale — t('expense.title') is MessageSource.getMessage('expense.title', locale). Interpolation with {{amount}} is MessageFormat placeholders. The fallbackLng is your default bundle when a locale-specific key is missing.
- Never hard-code user-facing strings; reference translation keys resolved per active language.
- react-i18next's useTranslation gives you t() for lookups and the i18n instance for changeLanguage.
- Interpolation ({{amount}}) injects dynamic values into translated strings without string concatenation.
- RTL support is more than translation: set dir="rtl" for languages like Arabic to mirror the layout.
Worked Code
// Setup: i18next + react-i18next
import i18n from 'i18next';
import { initReactI18next, useTranslation } from 'react-i18next';
i18n.use(initReactI18next).init({
resources: {
en: { translation: {
'expense.title': 'My Expenses',
'expense.add': 'Add Expense',
'expense.amount': 'Amount',
'expense.total': 'Total: {{amount}}',
}},
ar: { translation: {
'expense.title': 'مصاريفي',
'expense.add': 'إضافة مصروف',
'expense.amount': 'المبلغ',
'expense.total': 'المجموع: {{amount}}',
}},
},
lng: 'en',
fallbackLng: 'en',
});// Usage in components
function Header() {
const { t, i18n } = useTranslation();
return (
<header dir={i18n.language === 'ar' ? 'rtl' : 'ltr'}>
<h1>{t('expense.title')}</h1>
<p>{t('expense.total', { amount: '₹1,200' })}</p>
<button onClick={() => i18n.changeLanguage('ar')}>
العربية
</button>
</header>
);
}Interview-Ready Q&A
Adopt i18next with react-i18next. Extract all user-facing strings into per-language translation resource files keyed by stable identifiers (e.g. expense.title). Initialize i18next once with those resources, a default lng, and a fallbackLng. In components use the useTranslation hook's t() function to look up keys, and the i18n instance to switch languages. Add interpolation for dynamic values and the Intl API for date/number/currency formatting.
- 1Use translation keys, not hard-coded strings; i18next + react-i18next is the React standard.
- 2useTranslation provides t() for lookups and i18n.changeLanguage to switch locale at runtime.
- 3RTL = dir="rtl" plus logical CSS properties; interpolation handles dynamic values per language.