Add Internationalization (i18n) to Existing App
Integrate multilingual support with language selection and persisted user preference.
The route
6 steps to Done
- 01
Integrate i18n library
Add a robust internationalization library to provide translation support.
Preview prompt + verify gate ▾ Hide ▴
1. Add i18next and react-i18next as dependencies using the project's package manager (e.g., npm install i18next react-i18next). 2. In the src directory, create a file named i18n.js. 3. In i18n.js, import i18next, initReactI18next, and set up i18next.init with: language: 'en', fallbackLng: 'en', resources: {}, and use initReactI18next. 4. Export the configured i18next instance (or simply run the init code). 5. Ensure i18n.js is imported at the top level of the app (e.g., in index.js) so the configuration runs before any component renders. Do not include placeholder comments; provide real, executable code.
- ✓ i18next appears in package.json dependencies
- ✓ src/i18n.js file exists
- ✓ i18n.js imports i18next and initReactI18next
- ✓ i18n.js calls i18next.init with language set to 'en' and fallbackLng 'en'
- ✓ i18n.js is imported in the app entry point (e.g., index.js)
- 02
Create translation resource files
Store UI strings for each supported language.
Preview prompt + verify gate ▾ Hide ▴
Under a folder src/locales, create three JSON files: en.json, es.json, fr.json. Each file must contain the same five keys: "welcome", "login", "logout", "dashboard", "settings". Provide real English text for en.json (e.g., "Welcome"), proper Spanish translations for es.json (e.g., "Bienvenido"), and proper French translations for fr.json (e.g., "Bienvenue"). Do not use placeholders like "TODO" or empty strings. Ensure the JSON is valid and formatted.
- ✓ src/locales/en.json exists with at least five keys
- ✓ src/locales/es.json exists with the same keys as en.json
- ✓ src/locales/fr.json exists with the same keys as en.json
- ✓ All values are real translations, no placeholders
- 03
Refactor UI components to use translation function
Replace hardcoded UI strings with dynamic translations.
Preview prompt + verify gate ▾ Hide ▴
For each of the following component files: Header.jsx, LoginForm.jsx, Dashboard.jsx, Settings.jsx, do the following: a) Import { useTranslation } from 'react-i18next'. b) Inside the component, call const { t } = useTranslation(); c) Replace any hardcoded UI string that matches one of the five keys with {t('key')}. For example, replace "Welcome" with {t('welcome')}, "Login" with {t('login')}, etc. Ensure no remaining hardcoded instances of these texts exist. Do not add placeholder comments.
- ✓ Header.jsx imports useTranslation and uses t('welcome')
- ✓ LoginForm.jsx imports useTranslation and uses t('login')
- ✓ Dashboard.jsx imports useTranslation and uses t('dashboard')
- ✓ Settings.jsx imports useTranslation and uses t('settings')
- ✓ No hardcoded occurrences of "Welcome", "Login", "Logout", "Dashboard", or "Settings" remain in these files
- 04
Add language switcher and persist preference
Allow users to select a language and save their choice across sessions.
Preview prompt + verify gate ▾ Hide ▴
Create src/components/LanguageSwitcher.jsx that renders a <select> with three <option> elements: English (value 'en'), Spanish (value 'es'), French (value 'fr'). On change, call i18next.changeLanguage(selectedValue) and then localStorage.setItem('appLanguage', selectedValue). Import i18next at the top. Ensure the component is imported and placed in the main layout (e.g., in App.jsx). No placeholder UI; provide functional JSX and event handler.
- ✓ src/components/LanguageSwitcher.jsx file exists
- ✓ Dropdown includes options for 'en', 'es', and 'fr'
- ✓ On change, i18next.changeLanguage is called with the selected value
- ✓ On change, localStorage.setItem('appLanguage', selected) is executed
- ✓ LanguageSwitcher is imported and rendered in App.jsx (or equivalent root component)
- 05
Load persisted language on app startup
Initialize i18next with the saved language preference.
Preview prompt + verify gate ▾ Hide ▴
Edit src/i18n.js: before calling i18next.init, read const savedLang = localStorage.getItem('appLanguage'); Determine the startup language as savedLang if it exists, otherwise use navigator.language (first two letters) or fallback to 'en'. Pass this value to i18next.init via the 'lng' option. Ensure the code does not contain placeholders and that the logic gracefully handles missing values.
- ✓ src/i18n.js reads 'appLanguage' from localStorage
- ✓ i18next.init receives a 'lng' option based on savedLang or fallback
- ✓ Fallback to 'en' occurs when no saved language exists
- ✓ The initialized i18next instance reflects the determined language
- 06
Verify i18n functionality end‑to‑end
Test that translations appear, persist, and fallback correctly.
Preview prompt + verify gate ▾ Hide ▴
1. Launch the application; confirm the UI displays English (default). 2. Use the LanguageSwitcher to select Spanish; verify that all five UI texts change to their Spanish equivalents. 3. Refresh the browser; confirm the UI remains in Spanish. 4. Open developer tools, clear localStorage (remove 'appLanguage'), refresh; verify UI reverts to English. 5. Select French; verify UI texts change to French. 6. Document each step with a PASS or FAIL note indicating whether the expected behavior occurred.
- ✓ App starts in English by default
- ✓ Switching to Spanish updates all UI text to Spanish
- ✓ Page reload retains Spanish language
- ✓ Clearing localStorage and reloading reverts UI to English
- ✓ Switching to French updates UI text to French