Using Transifex Native to add internationalization (i18n) to a React app
Aman Mittal
Posted on May 9, 2022
Internationalization in an application provides multi-language support for a target set of app users that vary in region and language. Building such an application can be challenging, but there are many solutions available to add support for multiple languages in React ecosystem. One of these solutions is the Transifex. It allows a cloud service that serves translation phrases when implementing internationalization and localization in your React applications.
The translations are fetched continuously over the air (OTA) to the application. This way, you get to keep the translation as a separate layer from the application's development phase.
In this tutorial, let's learn how to integrate Transifex Native in a React application to use internationalization. We will walk you through setting up a new app on Transifex and the implementation steps required to integrate its SDK in a React application. After integrating the SDK, we will see how to create and manage translatable content that can be managed and updated on the cloud.
Prerequisites
To follow this tutorial, you will need:
- Transifex account
-
Node.js
14.x.x
or above installed - A basic understanding of React
You will find the complete code for the tutorial in this GitHub repository.
Setting up a React app
Let's start by creating a React app. Open up a terminal window and create a new React project using the create-react-app
toolchain.
npx create-react-app transifex-react
# after the project directory is created
# navigate inside it
cd transifex-react
After navigating inside the project directory, you will come across the familiar src
directory, part of the pre-defined folder structure that create-react-app
creates. This directory contains the source code of your React app. Let's build a general login page in the src/App.js
file as an example.
The login page will be a simple form with a title and a subtitle that describes the form, email and password input fields, and a button. The focus of the example is to keep it minimal and learn how to use Transifex Native SDK. However, the example will conclude when the app user fills in the details in the form and presses the sign-in button. After the button is pressed, an alert box is shown.
Open up the App.js
file and add the following code snippet:
import './App.css';
function App() {
const handleSubmit = event => {
event.preventDefault();
alert('Your form is submitted!');
};
return (
<div className="app">
<div className="form">
<h1>Login form</h1>
<p className="subtitle">Please enter your credentials to proceed.</p>
<form onSubmit={handleSubmit}>
<div className="input-container">
<label>Email</label>
<input type="text" name="email" required />
</div>
<div className="input-container">
<label>Password</label>
<input type="password" name="password" required />
</div>
<button className="button-container" type="submit">
<p className="button-text">Sign in</p>
</button>
</form>
</div>
</div>
);
}
export default App;
Also, add the following CSS styles to the App.css
file:
.app {
display: flex;
margin-top: 20px;
justify-content: center;
height: 100vh;
background-color: #fff;
}
.subtitle {
padding-bottom: 20px;
}
.button-container {
display: flex;
justify-content: center;
align-items: center;
border-radius: 8px;
background: #01d28e;
width: 100%;
height: 40px;
margin-top: 20px;
padding: 10px 20px;
}
.button-text {
color: #fff;
font-size: 18px;
font-weight: bold;
}
.input-container {
display: flex;
flex-direction: column;
gap: 8px;
margin: 10px;
}
From the terminal window, run the npm start
command to see the login page in action. You will see the following output in the browser window:
Installing Transifex Native SDK
To use Transifex Native, the first step is to install the Transifex JavaScript SDK. It also provides packages for different frameworks. Since the example app is built using React, also install the Transifex SDK extension for React.
To do so, run the following command from the project directory:
npm install @transifex/native @transifex/cli @transifex/react --save
Briefly, let's take a look at what each package does:
-
@transifex/native
is the core library package -
@transifex/cli
is the command line interface package. It collects all the localization phrases from the React app and pushes them to the Transifex Native project. It is enabled by adding a custom npm script to thepackage.json
file -
@transifex/react
is a library extension that provides components and hooks to internationalize phrases in the React app
Transifex Native SDK retrieves translation phrases using a custom CDN called Content Delivery Service (CDS). As a developer, you have to option to use Transifex's hosted service or opt for self-hosting.
Creating a Transifex Native project
After signing in to the Transifex account, start by creating a new project.
On the Add a new project page:
- Add the name of the project
- For Choose project type, select the Native option since the example app is using the JavaScript SDK. Transifex also offers File-based and Live project type options
- For Assign to team, select Create a new team for this project. You can also select Assign this project to an existing team and then select the team from the dropdown menu if you already have a team
- Under Select languages, set the source of the language to English. Under Target languages, select as many languages you want to provide translation support in your application. For the example app, select Spanish and French
After adding these details, click the Create project button to create a new Transifex project. You will see the following dashboard screen in the browser window:
To connect the Transifex Native SDK with your account, you need to add your Transifex account credentials to the project. Then, click Resources from the side menu on the dashboard. You will see the following screen:
Click the button Generate Native Credentials now at the bottom of the page. It will open a popup that will display the token
and secret
keys.
The token
is required to initialize the Transifex Native SDK in the React app. Both token
and secret
are used to push translation phrases from the React app to the Transifex service.
You will need both of these keys in your React app. Create a .env
file in the React app and paste them as shown in the following code snippet:
REACT_APP_TRANSIFEX_TOKEN=XXXX
REACT_APP_TRANSIFEX_SECRET=XXXX
The X
's represent the actual key in the above code snippet. After copying the keys to the .env
file, you can close the popup.
Initializing the Transifex Native SDK in the React app
To initialize the Transifex Native SDK, you need to import the @transifex/native
package in your React app. In the App.js
file, add the following import statement:
// rest of the import statements
import { tx } from '@transifex/native';
The tx
has a init
method that is used to initialize the Transifex Native SDK. It requires the value of the token to be passed. For example, add the following code snippet before the App
function:
tx.init({
token: process.env.REACT_APP_TRANSIFEX_TOKEN,
});
If you are using the latest version of the create-react-app
, you can directly read the value of environment variables defined inside the .env
file using the prefix process.env.REACT_APP_
.
Using Transifex in the React app
Transifex React extension package provides a T
component that will translate the text passed as a prop. It also provides LanguagePicker
that will display a dropdown menu with the enabled languages in your Transifex project.
The T
component has a required prop called _str
that accepts the translation phase as a string value. After the header and the subtitle, let's also add the LanguagePicker
component to show the dropdown menu to display language options.
Modify the JSX in the App
component as shown below:
return (
<div className="app">
<div className="form">
<h1>
<T _str="Login form" />
</h1>
<p className="subtitle">
<T _str="Please enter your credentials to proceed." />
</p>
<div className="picker">
<p className="picker-title">
<T _str="Select the language: " />
</p>{' '}
<LanguagePicker />
</div>
<form onSubmit={handleSubmit}>
<div className="input-container">
<label>
<T _str="Email" />
</label>
<input type="text" name="email" required />
</div>
<div className="input-container">
<label>
<T _str="Password" />
</label>
<input type="password" name="password" required />
</div>
<button className="button-container" type="submit">
<p className="button-text">
<T _str="Sign in" />
</p>
</button>
</form>
</div>
</div>
);
In the above code snippet, notice that the T
component is wrapped by the other HTML and React components to apply custom styling previously defined.
There are additional props available on the T
component.
Modify the App.css
file and the following code snippet to apply some styles for the text preceding the LanguagePicker
component.
/* After the rest of the code */
.picker {
display: flex;
margin-top: 10px;
padding: 10px;
flex-direction: row;
}
.picker-title {
font-size: 18px;
font-weight: bold;
margin-right: 10px;
}
If you have been running the dev server, you will need to restart the server to see the changes. Re-run the command npm start
from the terminal window and go back to the browser window to see the changes:
In the above screenshot, notice that the LanguagePicker
displays the languages that are enabled in the Transifex project (such as English, the source language, and target languages, Spanish and French).
Syncing translation strings with Transifex
The next step to enable translation is to sync the translation strings added in the previous section using the T
component with the Transifex project. After that, it will use the Transifex Native CLI to push collect all the translation phrases from the React app and push them to the Transifex project.
To do so, let's define a custom npm script in the package.json
file:
{
// ...
"scripts": {
"sync-translations": "./node_modules/.bin/txjs-cli push src/ --token=<TOKEN> --secret=<SECRET>"
}
}
In the above snippet, replace the <TOKEN>
and <SECRET>
with the actual values of the token
and secret
keys.
Next, run this npm script from the terminal window to push the translation phases.
npm run sync-translations
To verify that the translation strings are pushed to the Transifex project, go to the Transifex project in the browser window. You will see how the number of source strings increased (depending on how many translation strings were added in the React app).
As shown above, the current React app has six phrases that can be translated.
Adding translations
After pushing the translation strings, you can add the translation for each phrase. Then, from the dashboard screen, click the button Translate button. This will open a new page to the interface where you can manually add the translation for each phrase.
First, it will ask to select the source language. Choose French from the dropdown menu.
After selecting the language, all the strings are shown on the left-hand side. Select each of the strings, and then on the right-hand side, add the appropriate translation for each string depending on the target language. Click Save Translation to save the translated string.
Repeat this for all the phrases and both languages. After adding all the translations, the status of each phrase changes from gray to green. It is used to indicate that the translation of the specific phase is active and is translated.
Running the React app
Let's go back to the React app to see the translation in action. Since the syncing between Transifex and the React app is done by a hosted CDN-like service, there is no requirement to restart the server.
Exploring the Transifex React package
Transifex React package also provides other utilities in the form of hooks.
For example, you can use the useLanguages
hook to asynchronously fetch the supported languages (both source and target) from the Transifex project.
Another useful hook provided by the package is the useLocal hook. It is used to return a state variable with the currently selected locale. To see it in action, let's modify the App
function component:
import { tx } from '@transifex/native';
import { T, LanguagePicker, useLocale } from '@transifex/react';
import './App.css';
tx.init({
token: process.env.REACT_APP_TRANSIFEX_TOKEN,
});
function App() {
const currentLocale = useLocale();
const handleSubmit = event => {
event.preventDefault();
alert('Your form is submitted!');
};
return (
<div className="app">
<div className="form">
<h1>
<T _str="Login form" />
</h1>
<p className="subtitle">
<T _str="Please enter your credentials to proceed." />
<p>Currently selected locale is {currentLocale}.</p>
</p>
<div className="picker">
<p className="picker-title">
<T _str="Select the language: " />
</p>{' '}
<LanguagePicker />
</div>
{/* rest of the code remains same*/}
</div>
</div>
);
}
Here is the output after this step:
Conclusion
Thanks for reading this article. Using Transifex is quite simple to integrate, and I personally found it fun to use. Compared to an open-source alternative, it is paid if using Transifex hosting service but does provide self-hosting option.
Another feature I like about it is the Over the Air feature that allows for managing and updating translations in an automated way. Instead of having large json files, translatable phrases are maintained using an interface. It also bridges the gap between managing translations in different languages and the development of the application.
Further Reading
Check out the guide on implementing Localization in React apps using Transifex Native
Posted on May 9, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.