Using Talkr library for internationalization

map screenshot

Recently I returned to one of my older projects - Gdynia Open Data. I've added few more functionalities, including internationalization. I don't expect that this project will be used by anyone other than me but I wanted to refresh my knowledge about the aspect of internationalization in web apps.

So far I've used only one solution - react-i18next. The most popular among the developers, very mature and opinionated. However in this tiny project I wanted to try a new library. I had to translate around 30 phrases. Not much, probably not enough to use any additional tool.

First, I gathered information about the possible solutions and compared the bundle size.

Library Minified size [kb] Minified + Gzipped [kb]
react-i18next 23.3 7.1
react-intl 62.9 17.8
react-intl-universal 86.8 27.7
linguiJS - lingui/react - 6.7
- lingui/cli - ?
- lingui/macro - 274.5
- 2.5
- ?
- 81
react-translate-component 9.6 3.5
react-translated 10 3.5
talkr 2.1 0.996

All of them have pros and cons, and all of them will do their job. I decided to choose the one that has the smallest bundle size - talkr.

It's tiny, but it has some interesting features like:

  • zero dependecies

  • Typescript autocompletions for your translations

  • gender-adapter translations

  • react-native support

  • supports plural rules for translations

Implementation

First, wrap your application entry point - probably it is App in a Talkr provider.

App.tsx

import React from "react";
import { Talkr } from "talkr";
import en from "../../locales/en_translation.json";
import pl from "../../locales/pl_translation.json";

const App: React.FC = () => {
  return (
    <Talkr languages={{ en, pl }} defaultLanguage="en">
        // Rest of your app
    </Talkr>
  );
};

export default App;

Now lets' create the JSON files with translations, the same way you would do it using react-i18next.

/src/locales/en_translation.json

{
  "air temperature": "Air temperature",
  "surface temperature": "Surface temperature",
  "wind direction": "Wind direction",  
}

/src/locales/pl_translation.json

{
  "air temperature": "Temperatura powietrza",
  "surface temperature": "Temperatura powietrza",
  "wind direction": "Kierunek wiatru",  
}

These file are imported in the same place that we use Talkr provider (App.tsx in this example).

That's it. Library is configured and we can use it in any component.

/src/components/WeatherIndicator.tsx

import React from "react";
import { useT } from "talkr";

const WeatherIndicator: React.FC = () => {
  const { T } = useT();
  return (
      <h1>{T("air temperature")</h1>  
  )  
};

export default WeatherIndicator;

Other feature that you need if you have multiple languages in your app is the possibility of changing the language. Here's how to do it with talkr

/src/LanguageSwitcher/LanguageSwitcher.tsx

import React from "react";
import { useT } from "talkr";

const LanguageSwitcher: React.FC = () => {
  const { setLocale, locale } = useT();

  return (
    <div>
        <p>Current language: {locale}</p>
        <button onClick={() => setLocale("en")}>English</button>
        <button onClick={() => setLocale("pl")}>Polish</button>
    </div>
  );
};

export default LanguageSwitcher;

Typescript autocompletion for translation keys

Like in react-i18next there's a possibility to get the keys from your translation files and use them to type-check while using the usetT hook.

First, we have to create a new hook. Create a file translate.tsx somewhere in your project.

/src/translate.tsx

import { useT as useTr, Autocomplete, TParams, tr } from "talkr";
import en from "./locales/en.json";

type Key = Autocomplete<typeof en>;

export const useAutocompleteT = () => {
  const { locale, setLocale, languages, defaultLanguage } = useT();
  return {
    setLocale,
    locale,
    T: (key: Key, params?: TParams) =>
      tr({ locale, languages, defaultLanguage }, key, params),
  };
}

Now, we have to use this newly created hook instead of the useT directly from the library. Your IDE will suggest you the possible keys while using the T function.

/src/components/WeatherIndicator.tsx

import React from "react";
import { useAutocompleteT } from "translate";

const WeatherIndicator: React.FC = () => {
  const { T } = useAutocompleteT();
  return (
      <h1>{T("air temperature")</h1>  
  )  
};

export default WeatherIndicator;