Using Transifex Native to add internationalization (i18n) to a React app

amanhimself

Aman Mittal

Posted on May 9, 2022

Using Transifex Native to add internationalization (i18n) to a React app

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:

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
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

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:

ss1

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
Enter fullscreen mode Exit fullscreen mode

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 the package.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

ss2

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:

ss3

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:

ss4

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.

ss5

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
Enter fullscreen mode Exit fullscreen mode

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';
Enter fullscreen mode Exit fullscreen mode

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,
});
Enter fullscreen mode Exit fullscreen mode

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>
);
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

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:

ss6

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>"
  }
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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).

ss7

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.

ss8

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.

ss9

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.

ss10

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.

ss11

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>
  );
}
Enter fullscreen mode Exit fullscreen mode

Here is the output after this step:

ss12

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

💖 💪 🙅 🚩
amanhimself
Aman Mittal

Posted on May 9, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related