Essential internationalization library providing core functionality for JavaScript applications requiring multilingual support with ICU MessageFormat.
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
The @lingui/core/macro module provides compile-time translation helpers that are transformed by Babel during the build process. These macros enable optimal runtime performance by pre-compiling ICU MessageFormat strings and extracting translatable messages for localization workflows.
The primary macro for translating messages with multiple overloads supporting different usage patterns.
/**
* Translate a message descriptor with full metadata
* @param descriptor - Message descriptor with id, message, comment
* @returns Translated string (transformed at compile time)
*/
function t(descriptor: MacroMessageDescriptor): string;
/**
* Translate a template literal with interpolation
* @param literals - Template string array
* @param placeholders - Values for interpolation
* @returns Translated string (transformed at compile time)
*/
function t(
literals: TemplateStringsArray,
...placeholders: MessagePlaceholder[]
): string;
/**
* @deprecated Translate using specific I18n instance (use i18n._(msg`...`) instead)
* @param i18n - I18n instance to use for translation
* @returns Translation functions bound to the instance
*/
function t(i18n: I18n): {
(literals: TemplateStringsArray, ...placeholders: any[]): string;
(descriptor: MacroMessageDescriptor): string;
};
type MacroMessageDescriptor = (
| { id: string; message?: string }
| { id?: string; message: string }
) & {
comment?: string;
context?: string;
};
type MessagePlaceholder = string | number | LabeledExpression<string | number>;
type LabeledExpression<T> = Record<string, T>;Usage Examples:
import { t } from "@lingui/core/macro";
// Template literal with interpolation
const greeting = t`Hello ${name}!`;
// Message descriptor with metadata
const welcome = t({
id: "welcome.message",
message: `Welcome to our app, ${userName}!`,
comment: "Greeting shown on the welcome page"
});
// Simple message with auto-generated ID
const confirm = t({ message: "Are you sure?" });
// Message with explicit ID only
const error = t({ id: "error.network" });Handles pluralization using ICU MessageFormat plural rules.
/**
* Pluralize a message based on a numeric value
* @param value - Number or labeled expression determining plural form
* @param options - Plural form options (one, other, etc.)
* @returns Pluralized string (transformed at compile time)
*/
function plural(
value: number | string | LabeledExpression<number | string>,
options: ChoiceOptions
): string;
interface ChoiceOptions {
/** Offset for plural calculation (default: 0) */
offset?: number;
/** Exact match for zero */
zero?: string;
/** Singular form */
one?: string;
/** Dual form (some languages) */
two?: string;
/** Few form (some languages) */
few?: string;
/** Many form (some languages) */
many?: string;
/** Default/fallback form (required) */
other: string;
/** Exact numeric matches (e.g., "0": "no items") */
[digit: `${number}`]: string;
}Usage Examples:
import { plural } from "@lingui/core/macro";
// Basic pluralization
const itemCount = plural(count, {
one: "1 item",
other: "# items"
});
// Complex pluralization with offset
const commentCount = plural(commentCount, {
offset: 1,
"0": "No comments",
"1": "1 comment",
one: "1 other comment",
other: "# other comments"
});
// Using labeled expression
const messageCount = plural({count}, {
zero: "No messages",
one: "One message",
other: "{count} messages"
});Handles ordinal pluralization (1st, 2nd, 3rd, etc.) using ICU MessageFormat ordinal rules.
/**
* Select ordinal plural form (1st, 2nd, 3rd, etc.)
* @param value - Number or labeled expression for ordinal selection
* @param options - Ordinal form options
* @returns Ordinal string (transformed at compile time)
*/
function selectOrdinal(
value: number | string | LabeledExpression<number | string>,
options: ChoiceOptions
): string;Usage Examples:
import { selectOrdinal } from "@lingui/core/macro";
// Ordinal positioning
const position = selectOrdinal(place, {
one: "#st place",
two: "#nd place",
few: "#rd place",
other: "#th place"
});
// Birthday ordinals
const birthday = selectOrdinal({age}, {
one: "{age}st birthday",
two: "{age}nd birthday",
few: "{age}rd birthday",
other: "{age}th birthday"
});Conditional selection based on string values, similar to switch statements.
/**
* Select a message based on a string value
* @param value - String or labeled expression for selection
* @param choices - Object mapping values to messages
* @returns Selected string (transformed at compile time)
*/
function select(
value: string | LabeledExpression<string>,
choices: SelectOptions
): string;
interface SelectOptions {
/** Default/fallback choice (required) */
other: string;
/** Specific value matches */
[matches: string]: string;
}Usage Examples:
import { select } from "@lingui/core/macro";
// Gender selection
const pronoun = select(gender, {
male: "he",
female: "she",
other: "they"
});
// Status-based messages
const statusMessage = select({status}, {
pending: "Your order is being processed",
shipped: "Your order has been shipped",
delivered: "Your order has been delivered",
other: "Unknown status: {status}"
});Macros for defining messages without immediate translation, useful for message extraction and deferred translation.
/**
* Define a message for later translation
* @param descriptor - Message descriptor with metadata
* @returns MessageDescriptor object (not translated)
*/
function defineMessage(descriptor: MacroMessageDescriptor): MessageDescriptor;
/**
* Define a message using template literal syntax
* @param literals - Template string array
* @param placeholders - Values for interpolation
* @returns MessageDescriptor object (not translated)
*/
function defineMessage(
literals: TemplateStringsArray,
...placeholders: MessagePlaceholder[]
): MessageDescriptor;
/**
* Alias for defineMessage (shorter syntax)
*/
const msg: typeof defineMessage;Usage Examples:
import { defineMessage, msg } from "@lingui/core/macro";
// Define messages without translation
const messages = {
welcome: defineMessage({
id: "app.welcome",
message: "Welcome to our application!",
comment: "Main welcome message"
}),
goodbye: msg`Goodbye, ${userName}!`
};
// Later translate using I18n instance
const welcomeText = i18n._(messages.welcome);
const goodbyeText = i18n._(messages.goodbye, { userName: "Alice" });Helper function for creating labeled expressions with meaningful names.
/**
* Create a labeled placeholder for better message readability
* @param def - Object mapping labels to values
* @returns Labeled expression string
*/
function ph(def: LabeledExpression<string | number>): string;Usage Examples:
import { t, ph } from "@lingui/core/macro";
// Using ph for clearer placeholder names
const message = t`User ${ph({userName: user.name})} has ${ph({count: user.messages.length})} messages`;
// Equivalent to but more readable than:
const message2 = t`User ${user.name} has ${user.messages.length} messages`;All macro functions are transformed during the build process by @lingui/babel-plugin-lingui-macro. The macros:
Build-time transformation example:
// Source code
const message = t`Hello ${name}!`;
// Transformed code (simplified)
const message = i18n._("Hello {name}!", { name });While macros work with the global i18n instance by default, they can be used with specific instances:
import { i18n } from "@lingui/core";
import { msg } from "@lingui/core/macro";
// Define message
const welcomeMsg = msg`Welcome ${userName}!`;
// Translate with specific instance
const translated = i18n._(welcomeMsg, { userName: "Bob" });