Internationalization (i18n) and localization is critical in software development to expand the reach of your application. Sometimes, it’s even required to create an app with a specific language built into it. For instance, most government website pages are translated to the local and national language of their own country.
With the majority of websites relying on JavaScript, it’s no wonder that there are many popular JavaScript libraries set up to handle the internationalization of applications. Some of the most well-known libraries are:
For the purpose of this article, I’ll demonstrate how to use Lingui.js. This is a powerful library that not only handles internationalization in native JavaScript applications, but also in React, one of the most well-known JavaScript libraries. Lingui.js has a light size of only 5KB and is very easy for beginners to get started with.
Lingui.js is a relatively new internationalization library, but it offers some features that aren’t available in popular competitor libraries like react-intl and i18next. For example, Lingui.js is packed with macros that can be used to generate message syntax for components. Some other prominent features of Lingui.js are:
In general, Lingui.js can be integrated in any type of static application. And if you have a real-time application like a chat system or online game, then Lingui.js can be a great choice because it’s designed to be efficient for resource-intensive applications. For example, Caliopen (a unified messaging platform) is actively using Lingui.js.
In this article, we’ll work on a sample project to integrate Lingui.js within a React application. To make it easier, we will use the create-react-app package.
To follow along with this tutorial, you must already have Node.js installed on your system. Its latest version is packaged with tools like npm and npx so you don’t have to install them separately.
Our first step is to install the latest release of the create-react-app package on our local machine. To do so, open the console/terminal inside the desired folder on your system. After that, execute this command:
npx create-react-app my-app
It will take some time to install all the dependencies and set up a basic React app, so please be patient. After the setup is complete, run this command:
cd my-app
Now, you’ll be inside the project folder and ready to install Lingui.js.
Essentially, the developers of Lingui.js have divided the whole library into different modules. For now, we are interested in CLI, macro, and React. We also need Babel compiler core and babel-bridge to support older versions of Babel.
Let’s install all these dependencies in our React project:
npm i --save-dev @lingui/cli @lingui/macro @babel/core babel-core@bridge npm i --save @lingui/react
It’s time to set up Lingui.js by informing it about the location of the messages file, format to use, and the default UI language. To do so, you have to create a file named .linguirc
inside the root of your project. The content of this file should look like this:
{ "localeDir": "src/locales/", "srcPathDirs": ["src/"], "format": "minimal", "sourceLocale": "en" }
The src
directory will hold the source files of messages, whereas the Lingui.js will extract messages from these files and write them inside the language-specific folder. Each language (e.g., English, Urdu, Chinese, etc.,) will have their own subfolders inside the src/locales/
folder.
Also, it’s important to choose the right format for message translation. Some of the available formats include:
lingui
: Each message is returned in a pre-defined format like thisminimal
: Each message is returned in a simple JSON format like thispo
: Each message is returned as a fileLingui.js recommends the po
format. In general, it’s a matter of personal preference and the setup of your current application. Most of us might find the minimal
(i.e., JSON) format easier to read than others. So, in this tutorial, we’ll use the minimal
format. To learn more about each format, refer to this section of the docs.
package.json
At this point, we have to add some scripts in package.json
.
{ "scripts": { "add-locale": "lingui add-locale", "extract": "lingui extract", "compile": "lingui compile" } }
With the above commands, we will be able to generate new locales as well as compile and extract current locales in our application.
Executing the add-locale
script will enable us to create different languages for our user interface:
npm run add-locale en zh ur
To do so, you may have a look at the supported language codes on the official IANA website.
The CRA app already comes with a basic homepage. You can find this file under /src/App.js
. We will modify this file like this:
import React, { useState, useEffect } from 'react'; import { Trans } from '@lingui/macro'; import LanguageSelector from './components/LanguageSelector'; function App({ language, onLanguageChange }) { return ( <div className="App"> <LanguageSelector language={language} onChangeLangage={onLanguageChange} /> <header className="App-header"> <h1><Trans>Name of Countries</Trans></h1> </header> <ul> <li><Trans>United States</Trans></li> <li><Trans>Finland</Trans></li> </ul> </div> ); } export default App;
Did you notice that we are using a LanguageSelector
component?
This helps us to dynamically change the language of the user interface. It makes use of a simple HTML select dropdown. This is what this component looks like:
import React from 'react'; function LanguageSelector({ language, onChangeLangage }) { function handleChange(event) { event.preventDefault(); onChangeLangage(event.target.value); } return ( <div className="select"> <select onChange={handleChange} value={language}> <option value="en">English</option> <option value="ur">Urdu</option> <option value="zh">Chinese</option> </select> </div> ); } export default LanguageSelector;
Finally, we need to update our main /src/index.js
file. This file is responsible for importing the translations of the selected language and rendering the whole webpage.
import React, { useState } from 'react'; import ReactDOM from 'react-dom'; import { I18nProvider } from '@lingui/react'; import App from './App'; async function loadMessages(language) { return await import(`@lingui/loader!./locales/${language}/messages.json`); } function LocalizedApp() { const [catalogs, setCatalogs] = useState({}) const [language, setLanguage] = useState('en'); async function handleLanguageChange(language) { const newCatalog = await loadMessages(language); const newCatalogs = { ...catalogs, [language]: newCatalog }; setCatalogs(newCatalogs); setLanguage(language); } return ( <I18nProvider language={language} catalogs={catalogs}> <App language={language} onLanguageChange={handleLanguageChange} /> </I18nProvider> ); } ReactDOM.render(<LocalizedApp />, document.getElementById('root'));
Now that we have wrapped some text inside <Trans> … </Trans>
macro, it’s time to extract all those messages from the source code and then make key-value pairs inside each locale. The key will work as an ID where the value will be its translation in a specific language.
In the English language, the key and value pair will remain the same. But we have to change the values in other languages. By default, their value will be empty strings and we have to add the translations manually.
Execute the npm run extract
command to extract messages from the source code.
We have created a webpage that displays a list of two countries: Finland and the United States. Now, we have to translate the user interface into all supported languages.
Previously, we added the English, Chinese, and Urdu locale to our project. The default language is English, and Lingui.js is smart enough to automatically fill the English translations:
{ "Finland": "Finland", "Name of Countries": "Name of Countries", "United States": "United States" }
Now, open /src/locales/ur/messages.json
and replace its content with the below code.
{ "Finland": "فن لینڈ", "Name of Countries": "ممالک کا نام", "United States": "امریکہ" }
Similarly, open /src/locales/zh/messages.json
and update it with the following translations.
{ "Finland": "芬兰", "Name of Countries": "国家名称", "United States": "美国" }
At this point, we are ready to compile the translations so that we can use them in our application. To do so, execute the compile command npm run compile
.
To run the application, run the command npm start
.
Together, we learned how easy it is to integrate Lingui.js with a React app and add internationalization capabilities to your application.
One of the best perks of Lingui.js is that it can automatically manage the translation key-value pairs for all languages. This initializes the message with an empty string to prevent errors in the runtime. After that, you’ll simply add specific translations for different key-values and see your application in a new language.
Install LogRocket via npm or script tag. LogRocket.init()
must be called client-side, not
server-side
$ npm i --save logrocket // Code: import LogRocket from 'logrocket'; LogRocket.init('app/id');
// Add to your HTML: <script src="https://cdn.lr-ingest.com/LogRocket.min.js"></script> <script>window.LogRocket && window.LogRocket.init('app/id');</script>
Would you be interested in joining LogRocket's developer community?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowExplore use cases for using npm vs. npx such as long-term dependency management or temporary tasks and running packages on the fly.
Validating and auditing AI-generated code reduces code errors and ensures that code is compliant.
Build a real-time image background remover in Vue using Transformers.js and WebGPU for client-side processing with privacy and efficiency.
Optimize search parameter handling in React and Next.js with nuqs for SEO-friendly, shareable URLs and a better user experience.