Skip to main content

The core i18n functionality

@lingui/core package provides the main i18n object which manages message catalogs, active locale as well as translation and formatting of messages.


npm install --save @lingui/core


@lingui/core package exports the global instance of i18n object. Simply import it and use it:

import { i18n } from "@lingui/core"

// import plural rules for all locales
import { en, cs } from "make-plural/plurals"

i18n.loadLocaleData("en", { plurals: en })
i18n.loadLocaleData("cs", { plurals: cs })

* Load messages for requested locale and activate it.
* This function isn't part of the LinguiJS library because there are
* many ways how to load messages — from REST API, from file, from cache, etc.
async function activate(locale: string) {
const { messages } = await import(`${locale}/messages.js`)
i18n.load(locale, messages)


// returns the Czech translation of "Hello World"
const translation = i18n._("Hello World")

If you don't want to use the global i18n instance and you want to setup your own, you can use setupI18n method. You also need to set runtimeConfigModule for macros to work correctly:

// If you import `i18n` object from custom module like this:
import { i18n } from "./custom-i18n-config"

// ... then add following line to your Lingui configuration:
// "runtimeConfigModule": ["./custom-i18n-config", "i18n"]


Class i18n()

i18n.load(catalogs: Catalogs)

i18n.load(locale: string, catalog: Catalog)

Load catalog for given locale or load multiple catalogs at once.

import { i18n } from "@lingui/core"

const messages = {
"Hello": "Hello",
"Good bye": "Good bye",

// Just an example how catalog looks internally.
// Formatting of string messages works in development only.
// See note below.
"My name is {name}": "My name is {name}"

const messagesCs = {
"Hello": "Ahoj",
"Good bye": "Nashledanou",
"My name is {name}": "Jmenuji se {name}"

en: messagesEn,
cs: messagesCs

// This is the same as loading message catalogs separately per language:
// i18n.load('en', messagesEn)
// i18n.load('cs', messagesCs)

Don't write catalogs manually.

Code above contains an example of message catalogs. In real applications, messages are loaded from external message catalogs generated by compile command.

Formatting of messages as strings (e.g: "My name is {name}") works in development only, when messages are parsed on the fly. In production, however, messages must be compiled using compile command.

The same example would in real application look like this:

import { i18n } from "@lingui/core"

// File generated by `lingui compile`
import { messages: messagesEn } from "./locale/en/messages.js"

i18n.load('en', messagesEn)

i18n.activate(locale[, locales])

Activate a locale and locales. _ from now on will return messages in given locale.

import { i18n } from "@lingui/core"

i18n._("Hello") // Return "Hello" in English

i18n._("Hello") // Return "Hello" in Czech

i18n._(messageId[, values[, options]])

The core method for translating and formatting messages.

messageId is a unique message ID which identifies message in catalog.

values is an object of variables used in translated message.

options.message is the default translation (optional). This is mostly used when application doesn't use message IDs in natural language (e.g.: or Component.title).

import { i18n } from "@lingui/core"

// Simple message

// Message with variables
i18n._("My name is {name}", { name: "Tom" })

// Message with custom messageId
i18n._("", { name: "Tom" }, { message: "My name is {name}" }) string | Date[, format: Intl.DateTimeFormatOptions])

Returns: Formatted date string Format a date using the conventional format for the active language.

date is a Date object to be formatted. When date is a string, the Date object is created by new Date(date).

format is an object passed to the options argument of the Intl.DateTimeFormat constructor (optional).

import { i18n } from "@lingui/core"

const d = new Date("2021-07-23T16:23:00")

// Returns "7/23/2021", { timeStyle: "medium"})
// Returns "4:23:00 PM", { dateStyle: "medium", timeStyle: "medium"})
// Returns "Jul 23, 2021, 4:23:00 PM"

// Returns "23. 7. 2021"

i18n.number(value: number[, format: Intl.NumberFormatOptions])

Returns: Formatted number string

Format a number using the conventional format for the active language.

number is a number to be formatted.

format is an object passed to the options argument of the Intl.NumberFormat constructor (optional).

import { i18n } from "@lingui/core"

// Returns "12,345.678"

i18n.number(12345.678, { style: "currency", currency: "USD"})
// Returns "$12,345.68"

// Returns "12 345,678"

i18n.number(12345.678, { style: "currency", currency: "CZK"})
// Returns "12 345,68 Kč"


Returns: Instance of I18n

Initialize and return a new I18n instance. Usually you want to call it just once and then use returned i18n object across whole codebase.


You don't need to setup i18n instance

In most cases you can use the global i18n object exported from @lingui/core directly.

However, if you do need to setup your own i18n instance, remember to also set runtimeConfigModule work macros to work properly:

// If you import `i18n` object from custom module like this:
import { i18n } from "./custom-i18n-config"

// ... then add following line to your Lingui configuration:
// "runtimeConfigModule": ["./custom-i18n-config", "i18n"]
import { setupI18n } from "@lingui/core"

const i18n = setupI18n()

The factory function accepts one optional parameter, options:


Initial active locale.

import { setupI18n } from "@lingui/core"

const i18n = setupI18n({ locale: "en" })

// This is a shortcut for:
// const i18n = setupI18n()
// i18n.activate("en")


List of alternative locales (BCP 47 language tags) which are used for number and date formatting (some countries use more than one number/date format). If not set, active locale is used instead.

import { setupI18n } from "@lingui/core"

const i18n = setupI18n({
locale: "ar",
locales: ["en-UK", "ar-AS"]

// This is a shortcut for:
// const i18n = setupI18n()
// i18n.activate("en", ["en-UK", "ar-AS"])


Initial Messages.

import { setupI18n } from "@lingui/core"

const messages: {
en: require("./locale/en/messages").messages, // your path to compiled messages here
cs: require("./locale/cs/messages").messages // your path to compiled messages here
const i18n = setupI18n({ messages })

// This is a shortcut for:
// const i18n = setupI18n()
// i18n.load(messages)


Custom message to be returned when translation is missing. This is useful for debugging:

import { setupI18n } from "@lingui/core"

const i18n = setupI18n({ missing: "🚨" })
i18n._('missing translation') === "🚨"

This might be also a function which is called with active locale and message ID:

import { setupI18n } from "@lingui/core"

function missing(locale, id) {
alert(`Translation in ${locale} for ${id} is missing!`)
return id

const i18n = setupI18n({ missing })
i18n._('missing translation') // raises alert


Type of catalogs parameters in I18n.load method:

type Catalogs = {[locale: string]: Catalog}

// Example:
const catalogs: Catalogs = {
en: {
messages: {
"Hello": "Hello",
"Good bye": "Good bye"
cs: {
messages: {
"Hello": "Ahoj",
"Good bye": "Nashledanou"


Message catalog contains messages and language data (plurals). This object is usually generated in CLI:

type Catalog = {
languageData: {
plurals: Function
messages: Messages


Type of messages in Catalogs. It's a mapping of a messageId to a translation in given language. This may be a function if messages are compiled.

type Messages = {[messageId: string]: string | Function}

// Example
const messagesEn: Messages = {
"Hello": "Hello",
"Good bye": "Good bye"



Triggered after locale is changed or new catalog is loaded. There are no arguments.


Triggered when a translation is requested with i18n._ that does not exist in the active locale's messages. Information about the locale and message are available from the event.

i18n.on('missing', (event) => {
alert(`alert(`Translation in ${event.locale} for ${} is missing!`)`)