What is i18n?
Imagine you work as a developer at a growing startup, and your manager comes to you and says, "We are going to expand to a new country. In order to interact with local customers, you need to make changes to support their language and local requirements." This process is called internationalization, commonly referred to as i18n because there are 18 letters between "i" and "n" in "internationalization". In this post, we will focus on using the i18next JavaScript package with React.
i18n features
i18n has many use cases, including:
- Language support
- Date and time format changes (e.g., DD/MM/YYYY, YYYY/MM/DD)
- User language detection
- Currency representation (placement of currency symbol with digits varies by country), and more.
Installation
To use i18n in React, we need to install two packages:
npm i react-i18next i18next --save
The i18next
package is the core package that works with all JavaScript frameworks and apps, while react-i18next
is a plugin that makes it easy to use i18next with React.
Make React Multilinugual - Setup
Inside your app's src folder, create a new file called i18n.js (you can choose any name). Set up the file as follows:
import i18n from "i18next";
import { initReactI18next } from "react-i18next";
const resources = {} // We'll fill this later
i18n.use(initReactI18next)
.init({
resources,
lng: 'en', // default language option. en for english
interpolation: {
escapeValue: false
}
})
export default i18n
In the above code, we import the main i18next
package and the initReactI18next
class. Then we initialize the i18n class by passing the configuration data.
The resources
object is where we store the translations for different languages. The interpolation
key is used to prevent cross-site scripting attacks. The escapeValue
is set to false because the safety check is enabled in React by default, and we don't want i18n to perform the check again as it may slow down the application.
Next, import this file into src/index.js
as follows:
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import './i18n';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
Now you are ready to use it in the Components. Let's create a component called Home.js
with the following code.
import React from 'react'
import { useTranslation } from 'react-i18next';
const Home = () => {
const { t } = useTranslation()
return (
<div className='App-header'>
<p>{t('home_text')}</p>
</div>
)
}
export default Home
Our app should look like this now. As we did not add any language resources in i18n.js. The key name will be displayed.
Let's go and update both i18n.js
and Home.js
import i18n from "i18next";
import { initReactI18next } from "react-i18next";
const resources = { // language specific data
en: {
translation: {
'home_text': 'This is my home page',
'ask user': 'How are you?'
}
},
de: {
translation: {
'home_text': 'Dies ist meine Homepage'
}
}
}
i18n.use(initReactI18next)
.init({
resources,
lng: 'en', // default language option. en for english
interpolation: {
escapeValue: false
}
})
const Home = () => {
const { t } = useTranslation()
return (
<div className='App-header'>
<p>{t('home_text')}</p>
<p>{t('ask user')}</p>
</div>
)
}
In the above code, we use the useTranslation
hook from react-i18next
to access the translation function t()
. We can use t('home_text')
to retrieve the translated text for the key home_text
.
Now our app should look like this
Switch Language
To switch between languages, react-i18next
provides an i18n instance with several methods. Let's update Home.js
to include language switching:
const Home = () => {
const { t, i18n } = useTranslation()
const languages = {
en: 'English',
de: 'German'
}
return (
<div className='App-header'>
<p>{t('home_text')}</p>
<p>{t('ask user')}</p>
<div>
{ Object.keys(languages)
.map((lng) => <button
onClick={() => i18n.changeLanguage(lng)}
disabled={i18n.resolvedLanguage == lng}
key={lng}
>
{languages[`${lng}`]}
</button>
)}
</div>
</div>
)
}
With the above code you can switch between languages by using the provided buttons.
But there is a problem, when you switch to german instead of displaying the greeting it'll display the key name like this.
Fallback Language
To handle missing translation keys, we can specify a fallback language. Update the i18n.init
call in i18n.js
as follows:
i18n.use(initReactI18next)
.use(LanguageDetector)
.init({
resources,
lng: 'en',
interpolation: {
escapeValue: false
},
debug: true, // Will display debug options in console
fallbackLng: 'en' // If any key is missing, it will fallback to english
})
Language Detection
Providing an option to switch languages is good, but we can do better.
To automatically detect the user's preferred language in the browser, we can use the i18next-browser-languagedetector
package. Install the package and update i18n.js
as follows:
import LanguageDetector from 'i18next-browser-languagedetector';
const languageOptions = {
order: ['navigator', 'querystring'], // Define order and way to find user preference
lookupQuerystring: 'lng' // key name to find the preference
}
i18n.use(initReactI18next)
.use(LanguageDetector)
.init({
resources,
lng: 'en',
interpolation: {
escapeValue: false
},
detection: languageOptions,
debug: true,
fallbackLng: 'en'
})
We need to import LanguageDetector
from the package and pass it during i18n initialisation.
Also we need to pass options for language detection through detection
key.
There are many other options which you can pass for language detection which you can find in the documentation
Conclusion
Thank you for reading this blog post on making a React app multilingual using i18n. We covered the basics of i18n, installation, setup, language switching, fallback language, and language detection. Stay tuned for the next part where we'll explore more features provided by i18next.
If you have any corrections or questions, feel free to leave a comment. Thank you again for reading!
Thumbnail Photo by Amador Loureiro on Unsplash
Top comments (0)