Technologies to be used.
- ▶️ React JS 18.2.0
- ▶️ i18next 22.4.9
- ▶️ Vite JS 4.0.0
- ▶️ TypeScript 4.9.3
- ▶️ CSS vanilla (You can find the styles in the repository at the end of this post)
Creating the project.
We will name the project: multi-lang-app
(optional, you can name it whatever you like).
We create the project with Vite JS and select React with TypeScript.
Then we run the following command to navigate to the directory just created.
Then we install the dependencies.
Then we open the project in a code editor (in my case VS code).
First steps.
First we are going to install a library to be able to create routes in our app. In this case we will use react-router-dom .
Create a folder src/pages and inside create 2 files that will be our pages and will be very simple
- Home.tsx
- About.tsx
We will also create a simple Menu component so that you can move between paths and change the language from any path.
But first, let’s define the languages to use, in a separate file. In my case I will create them in a folder src/constants we create a file index.ts and add:
Now we create a folder src/components and inside the file Menu.tsx and add the following:
Finally we will create our router in the src/App.tsx file, adding the pages and the Menu component.
And that’s it, we have a simple two-route application.
Configuring i18n.
First we are going to install these dependencies.
react-i18next is the package that will help us to translate our pages in a React project in an easier way, but for that you need another package which is i18next to make the internationalization configuration.
So basically, i18next is the ecosystem itself, and react-i18next is the plugin to complement it.
Now let’s create a new file named i18n.ts we will create it inside the src folder (src/i18n.ts). Inside we are going to import the i18next package and we are going to access the use method because we are going to load the initReactI18next plugin to use the internationalization with React easier.
Now we will access its init method to add a configuration object.
- lng : Default language.
- fallbackLng : Language that will be loaded in case the translations the user is looking for are not available.
- resources : an object with the translations to be used in the application.
- interpolation.escapeValue : used to escape the values and avoid XSS attacks, we will set it to false, because React already does it by default.
In the resources part, it has to be created as follows:
The key of the object must be the language code, in this case “en ” of “English ” and then inside an object translation that inside will come all the translations, identified by key-value.
And it is important, keep the same name of the key of the objects, the only thing that changes is its value. Note how in both translation objects, inside they have the same title key .
This is what our file will look like once the translations have been added.
Finally this file will only be imported in the src/main.tsx file.
Using useTranslation.
Well now that we finished the i18n configuration, let’s use the translations we created. So, in the src/components/Menu.tsx file, we are going to use the useTranslation hook that react-i18next gives us.
We are going to use the hook that react-i18next gives us which is the useTranslation .
From this hook, we retrieve the object i18nm and the function t .
To use the translations is as follows:
By means of brackets we execute the function t that receives as parameter a string that makes reference to the key of some value that is inside the translation object that we configured previously. (Verify in your configuration of the file i18n.ts exists an object with the key home and that contains a value).
Depending on the default language you set, it will be displayed.
Well, now let’s switch between languages.
- First a function that executes every time the select changes.
- We access the value of the event.
- Through the object i18n we access the method changeLanguage and we pass the value by parameter.
Now if you switch between languages you will see how the texts of your app change.
The Menu.tsx file would look like this.
Now let’s go to the other pages to add the translation to the texts.
Home.tsx
About.tsx
Well, now let’s quickly show you how to interpolate variables.
Inside the t function, the second parameter is an object, which you can specify the variable to interpolate.
Note that I add the property name . Well then this property name, I have to take it very much in account
Now let’s go to a json file (but whatever I do in one, it has to be replicated in all the translations json files).
- First I add the new property user , since I didn’t have it before.
- Then using double brackets I add the name of the property I assigned before, which was name .
And in this way we interpolate values.
Moving translations to separate files.
But what happens when the translations are too many, then your i18n.ts file will get out of control. The best thing to do is to move them to separate files.
For this we will need to install another plugin.
This plugin will load the resources from a server, so it will be on demand.
Now we are going to create inside the public folder a i18n folder (public/i18n). And inside we are going to create .json files that will be named according to their translation, for example. The file es.json will be for the Spanish translations, the file it.json will be only for the Italian translations, etc. At the end we will have 3 files because in this app we only handle 3 languages.
Then, we move each translation object content from the i18n.ts file to its corresponding JSON file. For example the en.json file.
Once we have done that with the 3 files, we go to the i18n.ts and we are going to modify some things.
- First we are going to remove the resources property.
- We are going to import the i18next-http-backend package and by means of the use method, we pass it as parameter so that it executes that plugin.
Finally, we need to add a new property, which is backend that receives an object, which we will access to the loadPath property.
The loadPath property, receives a function that contains the language and must return a string. But a simpler way is to interpolate the lng variable.
This way we will have our path where the translations will be obtained, note that I am pointing to the public folder.
Now when you want to add a new language, just add the json file in the i18n folder inside public.
But there is one more step to do, if you notice in the loadedPath property, the host is http://localhost:5173 and when you upload it to production, the translations will not work, so we must validate if we are in development mode or not, in order to add the correct host.
One more tip is that the translations as they are in the backend could still be loaded while the page is ready, so it is advisable to manage a Suspense in the app.
The Suspense component pauses the app until it is ready, and in the fallback property is what is shown to the user while waiting for the application to be ready, here is a perfect place to put a loading or spinner.
You probably won’t notice a considerable improvement, since ours has very few translations. But it is a good practice .
Conclusion.
Creating a multi-language app is now easier thanks to i18n and its plugins.
I hope you liked this post and I also hope I helped you to understand how to make this kind of applications in an easier way. 🙌
Demo.
https://multi-lang-app-react.netlify.app/
Source code.
https://github.com/Franklin361/multi-lang-app
🔵 Don't forget to follow me also on X (Twitter): @Frankomtz030601
⚫ Don't forget to follow me also on GitHub: Franklin361