Overcoming language barriers is gradually becoming an integral part of software development, given in a world where users come from diverse linguistic backgrounds.
Internationalization (i18n) addresses this by adapting software for multiple languages, ensuring that users across the globe can interact with applications in their native language.
This process extends beyond translation to adapt various elements like numbers, date representations, and textual strings to suit different cultural norms.
One of the most popular libraries to implement internationalization is React i18next.
In this article, we take you through a step-by-step guide to leverage this powerful library to localize a React app. However, this process requires multiple files, which can quickly grow complex as the amount of data grows.
To simplify the process, we also discuss a popular alternative called Transifex Native, which can be directly integrated into your code and update all the translations over the air for you.
Localization & Internationalization
Localization (L10n) and internationalization (i18n) are key in enhancing user experience and expanding global reach.
While localization adapts your application to different languages and regions, internationalization is the process of designing a product to be adaptable to various languages.
This improves user engagement and opens up new markets for your business.
How to Implement Localization in React?
In this section, we will guide you through the essential steps and best practices for implementing localization in your React apps using i18next.
We’ll discuss everything from the prerequisites to the advanced i18n features so you can localize your React app like a pro.
Prerequisite
To add React i18next to your project, you need to install Node.JS and the npm to your computer. You must also have a basic understanding of HTML, CSS, and JavaScript.
Required Packages
- i18next: This is the core library for i18next, a powerful internationalization framework for JavaScript. It provides the fundamental functionalities needed for translating your application, including language detection, translation, and handling pluralization and formatting.
- react-i18next: This package integrates i18next with React, allowing for an easy and efficient way to include translation functionalities in your React components using hooks or higher-order components.
- i18next-browser-languagedetector: A plugin for i18next, this package automatically detects the user’s language in a browser environment, ensuring that your application displays in the user’s preferred language based on browser settings or specific language cues.
- i18next-http-backend: This backend plugin for i18next loads translations from a server using HTTP requests. It’s useful for scenarios where you want to manage and load translation resources from a remote server
Creating the React Project
You can start using your existing React app or create a new one. For this tutorial, we’ll set up a sample React project called my-react-app.
To create the project, run this command in your terminal:
npx create-react-app my-react-app
Installing and setting up i18next
To get started with the localization process, install both react-i18next and i18next packages using the following command:
npm install react-i18next i18next
The i18next provides you with the core i18n functionality, while react-i18next extends and connects it to the React.
- If you’d like to detect user language and load translation, you can use the following command:
npm install i18next-http-backend i18next-browser-languagedetector
- To install all dependencies mentioned above, use this command:
npm install i18next react-i18next i18next-browser-languagedetector i18next-http-backend
Create a i18n.js File
Create a new file i18n.js beside your index.js containing following content:
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import Backend from 'i18next-http-backend';
import LanguageDetector from 'i18next-browser-languagedetector';
i18n
// if you want your translations to be loaded from a professional CDN
.use(Backend)
// to detect user language
.use(LanguageDetector)
// to pass the i18n instance to react-i18next.
.use(initReactI18next)
// init i18next
.init({
fallbackLng: 'en',
debug: true,
interpolation: {
escapeValue: false, // not needed for react as it escapes by default
}
});
export default i18n;
Using i18n.use(initReactI18next), you can pass the i18n instance to react-i18next, which makes it available for all the components.
In the above code snippet, we start by importing the required dependencies, followed by configuring i18n.
- Observe how we incorporate additional libraries using the .use() method.
- Subsequently, we activate the debug mode for enhanced troubleshooting.
- English (en) is designated as the fallback language, ensuring that in instances where the desired locale is unavailable, the application defaults to English.
Now it’s time to add this to your index.js file.
Import to index.js File
For React 18.0 and above, use the following code to import i18n.js file to your index.js 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(
<App />
);
Note: If you need to access the t function or the i18next instance from outside of a React component, you can do this by simply importing your ./i18n.js and use the exported i18next instance using the following code:
import i18next from './i18n'
i18next.t('my.key')
Translate Your Content using t() and useTranslation()
To start translating your content, you can use the following hook inside your functional components:
import React, { Suspense } from 'react';
import { useTranslation } from 'react-i18next';
function Mycomponent() {
const { t, i18n } = useTranslation();
return <h1>{t('Welcome to React')}</h1>
}
// use react's Suspense
export default function App() {
return (
<Suspense fallback="loading">
<MyComponent />
</Suspense>
);
}
Translating Plain Text
The first step is to add translations in the JSON file. To do this, create a new file public/locales/<language_code>/translation.json
Here’s sample content for the file:
{
"title": "Welcome to react using react-i18next",
"description": {
"part1": "To get started, edit <1>src/App.js</1> and save to reload.",
"part2": "Switch language between English and Deutsch using buttons above."
}
}
Use withTranslation HOC
For some legacy cases, you may still be forced to use classes. To solve this issue, you can utilize the withTranslation HOC.
The withTranslation higher-order component (HOC) from react-i18next is a powerful tool for adding localization capabilities to your React components. It wraps your component and provides it with the t function, which is used for translating your content.
import React, { Component, Suspense } from 'react';
import { withTranslation } from 'react-i18next';
class LegacyComponentClass extends Component {
render() {
const { t } = this.props;
return (
<h1>{t('Welcome to React')}</h1>
)
}
}
const MyComponent = withTranslation()(LegacyComponentClass)
// i18n translations might still be loaded by the http backend
// use react's Suspense
export default function App() {
return (
<Suspense fallback="loading">
<MyComponent />
</Suspense>
);
}
Note: The withTranslation hook function takes one options argument. You can either pass in a namespace or an array of namespaces to load.
Use Trans Component
If you are looking to translate text containing a link component or formatting like <strong>, the Trans component can help you easily do so.
import React from 'react';
import { Trans } from 'react-i18next';
export default function MyComponent () {
return <Trans>Welcome to <strong>React</strong></Trans>
}
// the translation in this case should be
“Welcome to <1>React</1>”: “Welcome to <1>React and react-i18next</1>”
Define Language Switcher
A language switcher allows users to switch between different languages easily. Here’s a simple implementation using React:
import React from 'react';
import { useTranslation } from 'react-i18next';
function LanguageSwitcher() {
const { i18n } = useTranslation();
const changeLanguage = (language) => {
i18n.changeLanguage(language);
};
return (
<div>
<button onClick={() => changeLanguage('en')}>English</button>
<button onClick={() => changeLanguage('de')}>Deutsch</button>
{/* Add more buttons for other languages */}
</div>
);
}
export default LanguageSwitcher;
Debug Your Code
Debugging localized applications involves checking for missing keys, incorrect translations, and ensuring language switching works correctly. i18next provides a debug mode that logs helpful information to the console:
i18n.init({
// ... other options
debug: true,
});
When debug is set to true, i18next will log detailed information about the translation process, helping you quickly identify and fix issues.
Other Features of i18next You Should Be Using
Apart from the essential functions, i18next provides you with multiple localization features, including:
Interpolation
Interpolation is one of the most used functionalities in I18N. It allows integrating dynamic values into your translations. By default, these values get escaped to mitigate XSS attacks.
Here’s the keys to use:
{
"key": "{{what}} is {{how}}"
}
Keys, by default, are strings surrounded by curly brackets.
Pluralization
i18next handles plural forms by providing different keys based on the count. Here’s the keys for your code:
{
"key_one": "item",
"key_other": "items",
"keyWithCount_one": "{{count}} item",
"keyWithCount_other": "{{count}} items"
}
For more details, read the i18next documentation here.
Formatting
i18next allows you to format text within your translations. For example, you can format dates or numbers. Here’s the signature for your translation string:
{
"key": "Some format {{value, formatname}}",
"keyWithOptions": "Some format {{value, formatname(option1Name: option1Value; option2Name: option2Value)}}"
}
To use it for multiple formats:
{
"key": "Some format {{value, formatter1, formatter2}}"
}
Simplify Your React App Localization with Transifex
As we discussed above, for using the react-i18next for internationalization, you will need a JSON file that holds all your translatable content.
This process introduces new files that need manual data entry or automation on your side. However, there’s another alternative called Transifex Native that you can use in your code without any additional work.
All translatable content is managed by Transifex Native, and all translations are served over the air, with additional caching and grouping functionality that you control.
So you can simply focus on the code while Transifex takes care of the localization of your React app.
Here’s how you can easily integrate Transifex Native into your application.
Installation
Sign up for a 15-day free trial for Transifex to enjoy all the advanced localization features. Now, you can start localizing the React components using the @transifex/react library extension.
This library extends the functionality of Transifex Native JavaScript SDK.
To install, use the following code:
npm install @transifex/native @transifex/react @transifex/cli --save
Create a Transifex Native Project
Next, create a new project in the Transifex application. The Transifex Native project will provide the required credentials for linking your application to the content delivery system that will then serve all your content.
The t() Function
The Native SDK offers the T function to mark strings for localization. The T function is available as a React component and a JavaScript function.
import React from 'react';
import { T } from '@transifex/react';
function Example() {
return (
<div>
<T _str="Hello world" />
<T _str="Hello {username}" username={user} />
</div>
);
}
Push Translatable Content
To push content for translation, you will need the txjs-cli tool installed on your system as well as the tokens created in your Transifex project.
Now, use the CLI tool to scan all files in the selected folder and push the translatable content to your Transifex project using the following command.
$ npx txjs-cli push <SRC_FOLDER> --token=<PROJECT_TOKEN> --secret=<PROJECT_SECRET>
Preview Translations
To preview translated content within your application, you can switch between languages using the language picker.
The React components for the Native SDK come equipped with a language picker that seamlessly connects with the Native service to request translations.
Whether you work in a localhost development environment or a live setting, you can obtain the most up-to-date translations using the following command.
$ npx txjs-cli invalidate --token=<PROJECT_TOKEN> --secret=<PROJECT_SECRET>
When a new translation is added to Transifex, it becomes available over-the-air on your Transifex Native enabled application within an hour.
Display Translated Content
To display the content in the target translation language, use the tx.setCurrentLocale function, returning a Promise that resolves when content is loaded over the air from Transifex.
To get a list of supported languages, for instance, to create a language selector, use the tx.getLanguages function.
Best Practices for Developers for React Localization
Localizing a React application involves a comprehensive approach to ensure your app resonates with users across different cultures and languages.
Here are some best practices and useful tips to consider:
Understanding the cultural context
To localize for your target audience, it’s important to know their cultural nuances and sensitivities. This can include understanding local customs, traditions, and taboos. For instance, certain colors, symbols, or phrases may have different connotations in different cultures.
Once you do that, don’t just restrict localization to words. Consider localizing images, icons, and layouts as part of your strategy. Remember that what works in one culture might not be effective in another.
Keeping the codebase localization-friendly
Instead of hardcoding text, use keys that can be mapped to translated strings. This makes it easier to add or update translations without altering the codebase.
Avoid concatenating translated strings, as they can break the natural flow of a sentence, especially since sentence structures vary across languages. Instead, always translate complete sentences as a whole.
It’s also a good idea to design your UI to accommodate text expansion without breaking layouts as some translations may take up more space.
Integrating localization into the CI/CD pipeline
To implement continuous localization, set up an automated system using Transifex where translations are continuously updated and integrated, similar to how code is deployed. This keeps your app’s content current across all languages.
You can include localization testing in your automated test suites to catch issues like missing translations or layout problems in different languages.
Accessibility considerations in localized React apps
Ensure your localized content works well with screen readers and other assistive technologies. It’s also a good idea to be mindful of color contrast for readability, especially for users with visual impairments.
Cool Tricks for Enhanced Localization:
- Dynamic Locale Loading: Implement dynamic loading of locales to reduce your app’s initial load time. Load only the necessary languages based on user preference or browser settings.
- Locale-Specific Routing: Use different URLs for different languages (e.g., /en/about for English and /es/about for Spanish). This can improve SEO and user experience.
- Contextual Localization: Sometimes, the same word might need different translations depending on the context. Use context keys in your translation files to handle such scenarios.
Wrapping Up
Now you know how to utilize i18next to localize your React app. If you want to bypass the hassle of files and manual data management, you can alternatively install TX Native by integrating it directly into your code to reduce the workload for developers.
It eliminates the need for manual file transfers between TMS and your platform, allowing translators to focus on their work while developers concentrate on programming without the need to implement updates to the app.
Want to see how Transifex works with your code? Sign Up to get a free trial.