Introduction
In this tutorial, we will learn how to add multiple language support with react-i18next
library in React project.
react-i18next is a powerful internationalization framework for React / React Native which is based on i18next.
Table Of Content
- Create New Project
- Development
- Adding Translations
- Language Switcher
- Translation Optimization
- Final Result
- Reference
Demo
Create New Project
Step 1: Run code below to create new React project.
npx create-react-app react-lang-support
Once project created, check if it working by running this code
cd react-lang-support
npm start
Project opened successfully
Step 2: Install dependencies
Run code below to install two libraries react-i18next
and i18next
npm install react-i18next i18next
react-i18next
- is an internationalization-framework for React and React Native which is based on i18next
i18next
- is an internationalization-framework written in and for JavaScript
Development
Step 1: First we need to create new file called i18n.js
in our project
Step 2: Add following code inside i18n.js
file
import i18n from "i18next";
import { initReactI18next } from "react-i18next";
i18n
.use(initReactI18next) // passes i18n down to react-i18next
.init({
// the translations
// (tip move them in a JSON file and import them,
// or even better, manage them via a UI: https://react.i18next.com/guides/multiple-translation-files#manage-your-translations-with-a-management-gui)
resources: {
en: {
translation: {
"Welcome to React": "Welcome to React and react-i18next"
}
}
},
lng: "en", // if you're using a language detector, do not define the lng option
fallbackLng: "en",
interpolation: {
escapeValue: false // react already safes from xss => https://www.i18next.com/translation-function/interpolation#unescape
}
});
Now our file look like this
Step 3: Now we need to make our translation file accessible throughout our project. That's why we need to import i18n.js
file inside index.js
Add code below inside index.js
import "./i18n"
Check if you correctly following tutorial by looking to this screenshot below
Inside i18n.js
file, there is translation object which is consist of keys and values. From here we will use these keys inside our JSX file.
Step 4: Inside App.js
file lets import useTranslation
hook.
import { useTranslation } from 'react-i18next';
function App() {
return (
...
)
}
useTranslation
- gets the t
function and i18n
instance inside your functional component.
Step 5: As it stated above we will get t
function from useTranslation
hook inside App
component
function App() {
const { t } = useTranslation()
return (
...
)
}
Step 6: Now we can use t
function inside our JSX. t
function looks for key t('key')
from i18n.js
file. Our keys located inside translation object..
Overall our App.js look like this
import logo from './logo.svg';
import './App.css';
import { useTranslation } from 'react-i18next';
function App() {
const { t } = useTranslation()
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
{t('Welcome to React')}
</a>
</header>
</div>
);
}
export default App;
Check what we have done until this part
npm start
Result
As you can see, we got "Welcome to React and react-i18next" text from our i18n.js
file. It means we successfully configured react-i18next
and now ready for adding translations.
Adding translations
In this project, three languages will be used. They are Uzbek, Russian and English.
Step 1 For demonstration purposes add following translations inside i18n
file.
resources: {
uz: {
translation: {
welcome: "Xush kelibsiz",
goodbye: "Xayr"
}
},
ru: {
translation: {
welcome: "Добро пожаловать",
goodbye: "До свидания"
}
},
en: {
translation: {
welcome: "Welcome",
goodbye: "Goodbye"
}
}
}
Now our i18n
file look like this
import i18n from "i18next";
import { initReactI18next } from "react-i18next";
i18n
.use(initReactI18next) // passes i18n down to react-i18next
.init({
// the translations
// (tip move them in a JSON file and import them,
// or even better, manage them via a UI: https://react.i18next.com/guides/multiple-translation-files#manage-your-translations-with-a-management-gui)
resources: {
uz: {
translation: {
welcome: "Xush kelibsiz",
goodbye: "Xayr"
}
},
ru: {
translation: {
welcome: "Добро пожаловать",
goodbye: "До свидания"
}
},
en: {
translation: {
welcome: "Welcome",
goodbye: "Goodbye"
}
}
},
lng: "en", // if you're using a language detector, do not define the lng option
fallbackLng: "en",
interpolation: {
escapeValue: false // react already safes from xss => https://www.i18next.com/translation-function/interpolation#unescape
}
});
Now let see result on browser.
As you can see it is showing words from our i18n
file. But it is showing only English version.
Let change to Russian language. In order to do this, let's make change key lng
to ru
inside i18n
file
import i18n from "i18next";
import { initReactI18next } from "react-i18next";
i18n
.use(initReactI18next) // passes i18n down to react-i18next
.init({
// the translations
// (tip move them in a JSON file and import them,
// or even better, manage them via a UI: https://react.i18next.com/guides/multiple-translation-files#manage-your-translations-with-a-management-gui)
resources: {
uz: {
translation: {
welcome: "Xush kelibsiz",
goodbye: "Xayr"
}
},
ru: {
translation: {
welcome: "Добро пожаловать",
goodbye: "До свидания"
}
},
en: {
translation: {
welcome: "Welcome",
goodbye: "Goodbye"
}
}
},
lng: "ru", // change here
fallbackLng: "en",
interpolation: {
escapeValue: false // react already safes from xss => https://www.i18next.com/translation-function/interpolation#unescape
}
});
Let see result
As you can see it's showing Russian translation on screen. Wow we did it. Congratulations! So if you need Uzbek translation just change lng
to uz
. But question arises will be every time change language like in this hardcoded way ?
Answer is No. We will implement switcher to our project.
Language Switcher
Step 1: Inside App.js
add <select>
tag in order to give options for choosing language for user.
import logo from './logo.svg';
import './App.css';
import { useTranslation } from 'react-i18next';
function App() {
const { t } = useTranslation()
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<select>
<option>Choose language</option>
<option value="uz">Uzbek</option>
<option value="ru">Russian</option>
<option value="en">English</option>
</select>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
{t('welcome')}
<br />
{t('goodbye')}
</a>
</header>
</div>
);
}
export default App;
Now user will be able to choose language from <select>
dropdown. But it won't change language since we didn't implement function for changing language. In order to change language we will get instance of i18n
from useTranslation
hook.
Basic syntax of changing language using i18n
i18n.changeLanguage('en-US');
Step 2: We need to get instance of i18n
from 'useTranslation'
function App() {
const { t, i18n } = useTranslation()
return (
...
)
}
Now inside <select>
tag add onChange
method, this is where we get values from options provided and pass it to i18n
to change language
<select onChange={(e) => i18n.changeLanguage(e.target.value)}>
<option>Choose language</option>
<option value="uz">Uzbek</option>
<option value="ru">Russian</option>
<option value="en">English</option>
</select>
Final App.js
import logo from './logo.svg';
import './App.css';
import { useTranslation } from 'react-i18next';
function App() {
const { t, i18n } = useTranslation()
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<select onChange={(e) => i18n.changeLanguage(e.target.value)}>
<option>Choose language</option>
<option value="uz">Uzbek</option>
<option value="ru">Russian</option>
<option value="en">English</option>
</select>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
{t('welcome')}
<br />
{t('goodbye')}
</a>
</header>
</div>
);
}
export default App;
Result
Translation optimization
Step 1: Now, did you noticed our translations are located inside i18n.js
file. We haven't yet started splitting translations into multiple files (which is highly recommended for larger projects) but we already see that adding more languages would result in bundling unneeded translations into the application.
In order to separate our translation we will use package namely i18next-http-backend
, which helps us to load our translations
asynchronously.
Install i18next-http-backend
by running this code on terminal
npm install i18next-http-backend
Now we need to wire up i18next-http-backend into our i18n.js
file
import i18n from "i18next";
import { initReactI18next } from "react-i18next";
import backend from "i18next-http-backend"; // <--- import here
i18n
.use(initReactI18next) // passes i18n down to react-i18next
.use(backend) // <--- wire up here
.init({
// the translations
// (tip move them in a JSON file and import them,
// or even better, manage them via a UI: https://react.i18next.com/guides/multiple-translation-files#manage-your-translations-with-a-management-gui)
resources: {
uz: {
translation: {
welcome: "Xush kelibsiz",
goodbye: "Xayr"
}
},
ru: {
translation: {
welcome: "Добро пожаловать",
goodbye: "До свидания"
}
},
en: {
translation: {
welcome: "Welcome",
goodbye: "Goodbye"
}
}
},
lng: "en", // if you're using a language detector, do not define the lng option
fallbackLng: "en",
interpolation: {
escapeValue: false // react already safes from xss => https://www.i18next.com/translation-function/interpolation#unescape
}
});
Once we connected i18next-http-backend
, by default it will load translation from this path
'../public/locales/{lang}/translation.json'
This path considered to be the default for the i18next-http-backend
to load from.
Step 2: We need to create this path locales/{lang}/translation.json
inside public folder.
Now we need to remove this part of code from i18n.js
file
And add our translations inside translation.json
file for each language.
Now check result on browser
Final Result
Link to full source of tutorial here
Top comments (1)
❤💚💚💚 love it