Internationalization of TypeScript Applications: A Complete Guide with Examples

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

How to Stop Fearing and Start Localizing: Internationalization of TypeScript Applications

Have you ever wondered why some projects reach an international level while others remain "Russian-language startups"? Most often, the answer is simple: localization. Yes, that scary abbreviation i18n that gives many developers a nervous tic. But let's be honest: making a TypeScript application internationalized is not rocket science. It's just a set of correct approaches and tools. Today we'll break this down in practice, with live code examples, no fluff, and no abstruse theories.



Why TypeScript is an Ideal Candidate for i18n?

TypeScript gives us what plain JavaScript lacks: static typing. When it comes to translations, this becomes a superpower. Imagine: you change a translation key, and TypeScript screams before the app even runs: "Hey, you forgot to update the translation in the Spanish locale!". Agree, this is better than catching bugs in production.

Moreover, modern libraries for i18n in TypeScript allow you to generate types directly from translation files. This means autocompletion in the IDE will work like clockwork. No magic strings, no typos. Only clean, safe code.



Choosing a Library: i18next vs react-intl

There are two main players on the market: i18next and react-intl (part of FormatJS). Both work great with TypeScript, but their approaches differ.

  • i18next — the Swiss Army knife of internationalization. Supports pluralization, interpolation, contexts, lazy loading. Great for large projects.
  • react-intl — more lightweight, tailored for React. Uses a component-based approach (<FormattedMessage>) and a powerful ICU MessageFormat system.

In this article, we will use i18next with the official React adapter react-i18next. Why? Because it's the most popular stack and gives you maximum control.



Step-by-Step Setup: From Zero to the First Translation

Let's get straight to the point. Install the dependencies:

npm install i18next react-i18next i18next-browser-languagedetector

Now let's create a configuration file. This is the heart of our TypeScript application's internationalization.

// i18n.tsimport i18n from 'i18next';import { initReactI18next } from 'react-i18next';import LanguageDetector from 'i18next-browser-languagedetector';

import enTranslation from './locales/en/translation.json';import ruTranslation from './locales/ru/translation.json';

i18n .use(LanguageDetector) // automatic browser language detection .use(initReactI18next) // integration with React .init({ resources: { en: { translation: enTranslation }, ru: { translation: ruTranslation }, }, fallbackLng: 'en', // if translation is not found interpolation: { escapeValue: false, // React already escapes }, });

export default i18n;

Notice the fallbackLng. This is critically important for user experience: if a user comes with a browser set to Swahili, we will show them the English version, not a blank screen.



Translation File Structure

Let's create a locales folder and inside it subfolders for each language. Here is an example of the en/translation.json file:

{  "welcome": "Welcome to our application!",  "description": "This is a {{framework}} app with i18n support.",  "items": {    "zero": "No items",    "one": "One item",    "other": "{{count}} items"  }}

And here is its Russian counterpart:

{  "welcome": "Добро пожаловать в наше приложение!",  "description": "Это приложение на {{framework}} с поддержкой i18n.",  "items": {    "zero": "Нет элементов",\                

Blogs

Book Recommendations