ICU MessageFormat integration with pluralization, gender, and rich text element support for comprehensive internationalization. Provides both individual functions and intl instance methods for formatting messages with complex interpolation.
Formats messages using ICU MessageFormat syntax with variable interpolation and rich text support.
/**
* Format messages with ICU MessageFormat syntax
* @param config - Resolved intl configuration
* @param formatters - Formatter instances and message format getter
* @param descriptor - Message descriptor with id and optional default message
* @param values - Values for message interpolation including rich text elements
* @param opts - Additional formatting options
* @returns Formatted message as string or rich text elements
*/
function formatMessage<T>(
config: ResolvedIntlConfig<T>,
formatters: Formatters & { getMessageFormat: (...args: any[]) => IntlMessageFormat },
descriptor: MessageDescriptor,
values?: Record<string, PrimitiveType | T | FormatXMLElementFn<T>>,
opts?: IntlMessageFormatOptions
): string | T | Array<string | T>;Usage Examples:
import { formatMessage, createFormatters } from "@formatjs/intl";
const config = {
locale: 'en-US',
messages: {
greeting: 'Hello {name}!',
itemCount: 'You have {count, plural, =0 {no items} one {one item} other {# items}}',
boldText: 'This is <b>bold</b> text'
},
// ... other config
};
const formatters = createFormatters();
// Basic message formatting
const greeting = formatMessage(
config,
formatters,
{ id: 'greeting' },
{ name: 'Alice' }
);
// Result: "Hello Alice!"
// Pluralization
const count = formatMessage(
config,
formatters,
{ id: 'itemCount' },
{ count: 3 }
);
// Result: "You have 3 items"
// Rich text formatting (React example)
const richText = formatMessage(
config,
formatters,
{ id: 'boldText' },
{
b: (chunks) => <strong>{chunks}</strong>
}
);
// Result: ["This is ", <strong>bold</strong>, " text"]The $t method is a convenient alias for formatMessage available on intl instances, providing the same functionality with a shorter syntax.
/**
* Alias for formatMessage method available on intl instances
* @param descriptor - Message descriptor with id and optional default message
* @param values - Values for message interpolation including rich text elements
* @param opts - Additional formatting options
* @returns Formatted message as string or rich text elements
*/
$t<T>(
descriptor: MessageDescriptor,
values?: Record<string, PrimitiveType | T | FormatXMLElementFn<T>>,
opts?: IntlMessageFormatOptions
): string | T | Array<string | T>;Usage Examples:
// Using $t alias for shorter syntax
const intl = createIntl({
locale: 'en-US',
messages: {
greeting: 'Hello {name}!',
itemCount: 'You have {count, plural, =0 {no items} one {one item} other {# items}}'
}
});
// Both calls are equivalent
const greeting1 = intl.formatMessage({ id: 'greeting' }, { name: 'Alice' });
const greeting2 = intl.$t({ id: 'greeting' }, { name: 'Alice' });
// Common usage pattern
const welcomeMessage = intl.$t({
id: 'welcome',
defaultMessage: 'Welcome, {username}!'
}, {
username: user.name
});Defines a single message descriptor with type safety.
/**
* Define a single message descriptor
* @param msg - Message descriptor object
* @returns The same message descriptor for type safety
*/
function defineMessage<T>(msg: T): T;Defines multiple message descriptors with type safety and key preservation.
/**
* Define multiple message descriptors with type safety
* @param msgs - Record of message descriptors
* @returns The same record of message descriptors
*/
function defineMessages<
K extends keyof any,
T = MessageDescriptor,
U extends Record<K, T> = Record<K, T>
>(msgs: U): U;Usage Examples:
import { defineMessage, defineMessages } from "@formatjs/intl";
// Single message definition
const welcomeMessage = defineMessage({
id: 'welcome',
defaultMessage: 'Welcome, {name}!',
description: 'Greeting message for users'
});
// Multiple message definitions
const messages = defineMessages({
login: {
id: 'auth.login',
defaultMessage: 'Log in',
description: 'Login button text'
},
logout: {
id: 'auth.logout',
defaultMessage: 'Log out',
description: 'Logout button text'
},
profile: {
id: 'user.profile',
defaultMessage: 'User Profile',
description: 'Profile page title'
}
});
// Type-safe usage
const loginText = intl.formatMessage(messages.login);Describes a message with identifier, default content, and metadata.
interface MessageDescriptor {
/** Unique identifier for the message */
id?: string;
/** Human-readable description for translators */
description?: string | object;
/** Default message text or pre-compiled AST */
defaultMessage?: string | MessageFormatElement[];
}Support for variable interpolation and rich text elements in messages.
type PrimitiveType = string | number | boolean | null | undefined | Date;
type FormatXMLElementFn<T, R = T | string | (T | string)[]> = (
chunks: (T | string)[]
) => R;Usage Examples:
// Variable interpolation
const message = intl.formatMessage(
{ id: 'user.info', defaultMessage: '{name} is {age} years old' },
{ name: 'Alice', age: 25 }
);
// Date and number formatting within messages
const notification = intl.formatMessage(
{
id: 'notification',
defaultMessage: 'You have {count, number} new messages as of {date, date, short}'
},
{
count: 5,
date: new Date()
}
);
// Rich text with React elements
const richMessage = intl.formatMessage(
{
id: 'terms',
defaultMessage: 'I agree to the <link>Terms of Service</link>'
},
{
link: (chunks) => (
<a href="/terms" className="text-blue-500">
{chunks}
</a>
)
}
);
// Complex pluralization
const complexPlural = intl.formatMessage(
{
id: 'file.status',
defaultMessage: `{count, plural,
=0 {No files}
=1 {One file}
other {# files}
} {action, select,
upload {uploaded}
download {downloaded}
other {processed}
}`
},
{ count: 3, action: 'upload' }
);
// Result: "3 files uploaded"Support for pre-compiled message formats for better performance.
interface MessageFormatElement {
type: number;
value?: string;
// Additional properties based on element type
}Usage Examples:
// Pre-compiled messages for production optimization
const precompiledMessages = {
greeting: [
{ type: 0, value: "Hello " },
{ type: 1, value: "name" },
{ type: 0, value: "!" }
]
};
const intl = createIntl({
locale: 'en-US',
messages: precompiledMessages
});
// Works the same as string messages
const result = intl.formatMessage(
{ id: 'greeting' },
{ name: 'World' }
);Supported ICU MessageFormat features for complex message patterns.
Pluralization:
{count, plural, =0 {no items} one {one item} other {# items}}Selection:
{gender, select, male {He} female {She} other {They}} liked thisNumber Formatting:
{price, number, currency}
{percentage, number, percent}Date Formatting:
{date, date, short}
{time, time, medium}Nested Patterns:
{count, plural,
=0 {No {type, select, photo {photos} other {items}}}
one {One {type, select, photo {photo} other {item}}}
other {# {type, select, photo {photos} other {items}}}
}Message formatting includes comprehensive error handling for missing translations and format errors.
class MissingTranslationError extends IntlError<IntlErrorCode.MISSING_TRANSLATION> {
readonly descriptor?: MessageDescriptor;
constructor(descriptor: MessageDescriptor, locale: string);
}
class MessageFormatError extends IntlError<IntlErrorCode.FORMAT_ERROR> {
readonly descriptor?: MessageDescriptor;
readonly locale: string;
constructor(message: string, locale: string, descriptor?: MessageDescriptor, exception?: Error);
}