Internationalization (also known as i18n) allows your application to be available in different locales. The aim of internationalization is to remove the barriers to localizing or deploying an application internationally. Application’s users may speak different languages and have varying conventions for numbers, dates or strings.
In Javascript there are plenty of libraries for internationalization: i18next
, node-gettext
or gloablize
.
However, in this article we will focus on using the i18next
library with React.js.
React-i18next
react-i18next
is an internationalization framework that can be used with both React and React Native apps. This framework
is based on i18next
.
The i18next
and react-i18next
is the most popular duo when it comes to React localization. Here are the main
advantages of this solution for your application:
i18next
can be used in any Javascript environment with any UI framework,- the library was created in 2011 and is available open source,
- there is plenty of extensions that can be used with this solution.
Setup project
In this article I’ll be using simple React project bootstrapped with Create React App (CRA) with the following command:
npx create-react-app react-i18n-project
After creating the project you can change the directory and start the server:
cd react-i18n-project
npm start
Add the dependencies
As stated previously react-i18next
is based on i18next
, so we will need both packages to successfully translate
our app:
npm install react-i18next i18next i18next-browser-languagedetector --save
Speaking of extensions, i18next-browser-languagedetector
is an i18next
plugin used to detect user language in the
browser. It also supports features as cookies, localStorage, query strings and more.
Getting started
Let’s start with basic config listed in i18n.js
file:
import i18n from 'i18next'
import { initReactI18next } from 'react-i18next'
import LanguageDetector from 'i18next-browser-languagedetector'
i18n
.use(LanguageDetector)
.use(initReactI18next)
.init({
debug: true,
fallbackLng: 'en',
resources: {
en: {
translation: {
// here we will place our translations...
},
},
},
})
export default i18n
We should have it imported in the index.jsx
file:
import React from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import App from './App'
// import i18n (needs to be bundled ;))
import './i18n'
const root = createRoot(document.getElementById('root'))
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
)
Let’s quickly go through each line of the configuration file:
.use(LanguageDetector)
- detects user language,.use(initReactI18next)
- passes thei18n
instance to the module ofreact-i18next
,.init({...
- inits i18next,debug: true
- helps in i18n debugging with browser’s console,fallbackLng: 'en'
- sets default language to English,
Create translation files
In this section we are going to learn how to translate normal text from one language to another. We need to have some place
to store translated texts in all languages that we need. Let’s create directory named eg. locales
and inside we should
create JSON files with names corresponding to the language codes of the translations - es
for Spanish, fr
for French and
so on.
// locales/es.json
{
"welcome": "Angular es mi framework Javascirpt favorito",
"article": {
"heading": "Por qué me gusta tanto Angular",
}
};
// locales/fr.json
{
"welcome": "Angular est mon framework Javascirpt préféré.",
"article": {
"heading": "Pourquoi j'adore Angular",
}
};
Disclaimer: I have no knowledge of Spanish and French. I used Google Translate to take these texts!
The last part of the setup is to import those JSON files to out config file:
// ...
import translation_es from './locales/es.json';
import translation_fr from './locales/fr.json';
// ...
resources: {
es: {
translations: translation_es
},
fr: {
translations: translation_fr
}
}
Using Trans component and useTranslation hook
Now we have the translations ready. Of course the folders structure and file names may differ in your applications. In much more complex apps it is recommended to come with better system where you can have separate translation files for different views in your app or even use lazy loading to drastically improve your application performance.
To use the translations and translate the content we can use to solutions provided by i18next-react
.
Trans component
import React from 'react'
import { Trans, useTranslation } from 'react-i18next'
function MyComponent() {
return (
<h1>
<Trans i18nKey="welcome">
Angular is my favorite Javascript framework
</Trans>
</h1>
)
}
Please keep in mind that according to the documentation: “s long you have no React/HTML nodes integrated into a cohesive
sentence (text formatting like strong, em, link components, maybe others), you won’t need it - most of the times you
will be using the good old t
function”. So, here is an alternative way to translate your content.
useTranslation
import React, { Suspense } from 'react'
import { useTranslation } from 'react-i18next'
function MyComponent() {
const { t, i18n } = useTranslation()
return <h1>{t('welcome')}</h1>
}
How to switch languages
Let’s add s simple component with buttons that allows users to switch the language of our app.
import React, { Suspense } from 'react'
import { useTranslation } from 'react-i18next'
const languages = {
en: { displayName: 'English' },
es: { displayName: 'Spanish' },
}
function MyComponent() {
const { t, i18n } = useTranslation()
return (
<div>
<h1>{t('welcome')}</h1>
<div>
<button
onClick={() => i18n.changeLanguage(languages.en)}
style={{
fontWeight:
i18n.resolvedLanguage === languages.en ? 'bold' : 'normal',
}}
>
{languages.en.displayName}
</button>
<button
onClick={() => i18n.changeLanguage(languages.es)}
style={{
fontWeight:
i18n.resolvedLanguage === languages.es ? 'bold' : 'normal',
}}
>
{languages.es.displayName}
</button>
</div>
</div>
)
}
As you can see in the code example above useTranslation
hook gives us possibility to read current active language and
change the language of the whole app.
Here we have added two buttons that switch the language of the app and the font weight of the text inside of them indicates the active language.
As you may remember form the previous paragraphs we have installed i18next-browser-languagedetector
and added it to
our config file. i18next
tries to detect the browser language and automatically use that language if the corresponding
translation file is available.
Speaking of our buttons for switching languages - manually selected language is persisted in the localStorage
and it will
be used as preferred language even after closing the browser and opening the app the other day.
Summary
There are many other topics to cover in terms of internationalization React apps using i18next
. In the next articles
I’m going to explain how to handle plurals, interpolation and formatting dates. I hope that it was a great introduction
to the i18n, peace 🏻.