Exploring “ttag” API in ReactJS: Enhancing your i18n experience

zen8labs
zen8labs
Published in
4 min readAug 1, 2024

Internationalization (i18n) is essential for reaching a global audience in modern web development. Supporting multiple languages enhances accessibility, improves user experience, and broadens your application’s reach. The powerful and flexible "ttag" library simplifies translation management in ReactJS applications.

At zen8labs, we understand the importance of creating applications that resonate with a diverse user base. That’s why we utilize "ttag" to ensure our applications are not only functional but also accessible to users worldwide.

A deeper dive into the “ttag” API

In this section, we will delve deeper into the powerful API that "ttag" offers for internationalizing your ReactJS applications. "ttag" provides a variety of functions and tools that simplify the process of managing translations, making your application more accessible and user-friendly to a global audience. Whether you are building a new project or enhancing an existing one, integrating "ttag" will make it easier to manage translations and improve the user experience.

Core functions of “ttag”

“t” Function: Simple and effective translation

The “t” function is the cornerstone of "ttag". It is used to mark text strings for translation, making it easy to identify and translate content within your application.

import { t } from 'ttag'; 

const greeting = t"Hello, World!";

console.log(greeting);

“jt” Function: JSX-Compatible Translations

The “jt” function is similar to t but is designed for JSX content. It allows for seamless interpolation of JSX elements within translated strings, making it ideal for dynamic content in your components.

import { jt } from 'ttag'; 

const link = <a href="/docs">docs</a>;

const message = jt"Check out our ${link}";

console.log(message);

Locale management

“addLocale” Function: Adding new locales

The “addLocale” function allows you to add new locales to your application. This function takes two parameters: the locale identifier and the locale data (usually imported from a JSON file).

import { addLocale } from 'ttag';

import en from '../i18n/en.po.json';

import vi from '../ i18n /vi.po.json';

addLocale('en', en);

addLocale('vi', vi);

“useLocale” Hook: Setting the current locale

The “useLocale” hook is used to set and get the current locale of your application. By calling this hook, you ensure that the correct translations are applied based on the user’s selected language.

import { useLocale } from 'ttag';

const App = () => {

const locale = 'en';

useLocale(locale);

return (

<div>

<p>{t"Welcome to our website!"}</p>

</div>

);

};

Handling dynamic translations

Importing translations dynamically

For applications that support multiple languages, it’s crucial to load translations dynamically. This ensures that only the necessary translations are loaded, optimizing performance and reducing load times.

import { t, jt } from "ttag";

import logo from "./assets/react.svg";

import "./App.css";

import { addLocale, useLocale } from "ttag";

import { useEffect, useState } from "react";

const LOCALE_COOKIE = "__locale";

function getLocale() {

return localStorage.getItem(LOCALE_COOKIE) || "en";

}

function saveLocale(locale) {

localStorage.setItem(LOCALE_COOKIE, locale);

}

const setLocale = (locale) => (ev) => {

ev.preventDefault();

saveLocale(locale);

window.location.reload();

};

const LangSwitcher = () => (

<>

<h2>{t"Switch lang"}</h2>

<div className="lang-switch">

<a href="/" onClick={setLocale("vi")}>

vi

</a>

<a href="/" onClick={setLocale("en")}>

en

</a>

</div>

</>

);

const App = () => {

const [dataLoaded, setDataLoaded] = useState(false);

const appLink = <span key="1">src/App.js</span>;

const locale = getLocale();

useEffect(() => {

import("../i18n/${locale}.po.json").then((module) => {

const localeObj = module.default;

addLocale(locale, localeObj);

setDataLoaded(true);

});

}, [locale]);

useLocale(locale);

if (!dataLoaded) {

return <div></div>;

}

return (

<div className="App">

<header className="App-header">

<LangSwitcher />

<img src={logo} className="logo" alt="logo" />

<p>{jt"Edit ${appLink} and save to reload."}</p>

<a className="App-link" href="https://reactjs.org" target="_blank" rel="noopener noreferrer">

{t"Learn React"}

</a>

<br></br>

<a className="App-link" href="https://ttag.js.org" target="_blank" rel="noopener noreferrer">

{t"Learn ttag"}

</a>

</header>

</div>

);

};

export default App;

Advanced features

Contextual translations

“ttag” allows you to add context to your translations, making them more precise and relevant. This is especially useful for words or phrases that might have different meanings in different contexts.

import { t, c } from 'ttag'; 

const buttonLabel = c('Save button label').t"Save";

console.log(buttonLabel);

Pluralization

Handling plural forms in different languages can be complex. “ttag” simplifies this with automatic pluralization support.

import { ngettext, msgid } from 'ttag';

const itemCount = 5;

const message = ngettext(

msgid"${itemCount} item",

"${itemCount} items",

itemCount

);

console.log(message);

Integrating with build tools

To streamline the translation process, “ttag” can be integrated into your build pipeline. This ensures that your translation files are always up to date and synchronized with your source code.

Extracting translations

Use the “ttag-cli” tool to extract translations from your source code into .po files.

npx ttag extract -o i18n/en.po src/ 

npx ttag extract -o i18n/vi.po src/

Updating translation files

To keep your translation files current with any changes in your source code, use the update command:

npx ttag update i18n/vi.po src/

npx ttag update i18n/en.po src/

Loading translations

Let’s make our translation .po file loadable. As webpack supports json load out of the box — let’s transform .po to .json with ttag-cli:

npx ttag po2json i18n/en.po > i18n/en.po.json 

npx ttag po2json i18n/vi.po > i18n/vi.po.json

Conclusion

"ttag" establishes itself as a compelling solution for i18n in ReactJS applications. Its streamlined API, automatic pluralization, contextualization capabilities, and robust feature set make it an attractive option for developers seeking to craft internationalized user experiences. Whether you’re embarking on a new project or seeking to enhance an existing one, "ttag" is worth considering as your weapon of choice in the realm of ReactJS i18n. For other considerations, why not try zen8labs?

Dat Le, Software Engineer

--

--

zen8labs
zen8labs
Editor for

We are a global tech consultancy company specializing in customer experience design, digital transformation and enterprise modernization. Email: hi@zen8labs.com