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

4 min read
zen8labs Exploring TTag Api in RectJS

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!"; 


“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}"; 


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';


  return (


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




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) => {





const LangSwitcher = () => ( 


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

<div className="lang-switch"> 

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



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






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



}, [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 className="App-link" href="https://ttag.js.org" target="_blank" rel="noopener noreferrer"> 

{t"Learn ttag"} 






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"; 



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",




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


"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 

Related posts

In Go, slices are one of the most important data structures, providing developers with a way to work with and manage collections of data similar to what we use at zen8labs. In this blog, I will introduce some internal aspects of slices and highlight some pitfalls to avoid when using slices in Go.
5 min read
One of the key strengths of Odoo is its modular architecture, which allows developers to extend and modify existing modules to their needs. In zen8labs' latest blog, we look at some ways that you can use Odoo to your prosperity.
3 min read
For beginners exploring Redux, you'll come across many tutorials using Redux Thunk or Redux Saga to manage async actions. However, here at zen8labs we can give recommendations between using Redux Saga over Redux Thunk in large-scale projects. Read them in our latest blog.
4 min read