Internationalize JS apps with APIs to format dates, numbers, and strings, including pluralization and handling translations.
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Create configured intl instances that provide all formatting methods with shared locale and message configuration. The intl instance serves as a centralized formatting hub with consistent configuration across all operations.
Creates an intl instance with the provided configuration and optional cache.
/**
* Create intl object with configuration and optional cache
* @param config - Intl configuration object
* @param cache - Optional cache for formatter instances to prevent memory leaks
* @returns IntlShape instance with all formatting methods
*/
function createIntl<T = string>(
config: IntlConfig<T>,
cache?: IntlCache
): IntlShape<T>;Usage Examples:
import { createIntl } from "@formatjs/intl";
// Basic configuration
const intl = createIntl({
locale: 'en-US',
messages: {
welcome: 'Welcome, {name}!',
itemCount: 'You have {count, plural, =0 {no items} one {one item} other {# items}}'
}
});
// Advanced configuration with timezone and custom formats
const intl = createIntl({
locale: 'en-US',
timeZone: 'America/New_York',
messages: { /* ... */ },
formats: {
number: {
currency: { style: 'currency', currency: 'USD' }
},
date: {
short: { month: 'numeric', day: 'numeric', year: '2-digit' }
}
},
defaultLocale: 'en',
onError: (error) => console.error('Intl Error:', error)
});
// With shared cache for memory optimization
import { createIntlCache } from "@formatjs/intl";
const cache = createIntlCache();
const intl1 = createIntl({ locale: 'en-US' }, cache);
const intl2 = createIntl({ locale: 'en-GB' }, cache);Configuration object for creating intl instances.
interface IntlConfig<T = string> {
/** Primary locale for formatting */
locale: string;
/** Message catalog as strings or pre-compiled MessageFormatElements */
messages?: Record<string, string> | Record<string, MessageFormatElement[]>;
/** Timezone for date/time formatting */
timeZone?: string;
/** Custom format definitions */
formats?: CustomFormats;
/** Default locale for fallback */
defaultLocale?: string;
/** Default format definitions */
defaultFormats?: CustomFormats;
/** Default rich text elements for message formatting */
defaultRichTextElements?: Record<string, FormatXMLElementFn<T>>;
/** Whether to fallback on empty string messages */
fallbackOnEmptyString?: boolean;
/** Error handler function */
onError?: OnErrorFn;
/** Warning handler function */
onWarn?: OnWarnFn;
}The complete intl instance interface combining configuration and formatting methods.
interface IntlShape<T = string> extends ResolvedIntlConfig<T>, IntlFormatters<T> {
/** Low-level formatter instances */
formatters: Formatters;
}
interface IntlFormatters<TBase = unknown> {
/** Format date/time ranges */
formatDateTimeRange(from: Date, to: Date, opts?: FormatDateOptions): string;
/** Format dates */
formatDate(value: Date | string | number, opts?: FormatDateOptions): string;
/** Format times */
formatTime(value: Date | string | number, opts?: FormatDateOptions): string;
/** Format dates to parts */
formatDateToParts(value: Date | string | number, opts?: FormatDateOptions): Intl.DateTimeFormatPart[];
/** Format times to parts */
formatTimeToParts(value: Date | string | number, opts?: FormatDateOptions): Intl.DateTimeFormatPart[];
/** Format relative time */
formatRelativeTime(value: number, unit?: Intl.RelativeTimeFormatUnit, opts?: FormatRelativeTimeOptions): string;
/** Format numbers */
formatNumber(value: number | bigint, opts?: FormatNumberOptions): string;
/** Format numbers to parts */
formatNumberToParts(value: number | bigint, opts?: FormatNumberOptions): Intl.NumberFormatPart[];
/** Format plural rules */
formatPlural(value: number, opts?: FormatPluralOptions): LDMLPluralRule;
/** Format messages with ICU MessageFormat */
formatMessage(descriptor: MessageDescriptor, values?: Record<string, any>, opts?: IntlMessageFormatOptions): string | TBase | Array<string | TBase>;
/** Alias for formatMessage */
$t(descriptor: MessageDescriptor, values?: Record<string, any>, opts?: IntlMessageFormatOptions): string | TBase | Array<string | TBase>;
/** Format lists */
formatList<T extends TBase>(values: readonly (string | T)[], opts?: FormatListOptions): string | T | Array<string | T>;
/** Format lists to parts */
formatListToParts<T extends TBase>(values: readonly (string | T)[], opts?: FormatListOptions): Part[];
/** Format display names */
formatDisplayName(value: string, opts: FormatDisplayNameOptions): string | undefined;
}Define custom format configurations for reuse across formatting operations.
interface CustomFormats extends Partial<Formats> {
/** Custom relative time formats */
relative?: Record<string, Intl.RelativeTimeFormatOptions>;
}
interface CustomFormatConfig<Source = string> {
format?: string;
}Usage Examples:
const intl = createIntl({
locale: 'en-US',
formats: {
number: {
currency: {
style: 'currency',
currency: 'USD',
minimumFractionDigits: 2
},
percentage: {
style: 'percent',
minimumFractionDigits: 1
}
},
date: {
short: {
month: 'numeric',
day: 'numeric',
year: '2-digit'
},
long: {
weekday: 'long',
year: 'numeric',
month: 'long',
day: 'numeric'
}
},
relative: {
long: {
numeric: 'always',
style: 'long'
}
}
}
});
// Use custom formats
const price = intl.formatNumber(29.99, { format: 'currency' });
const date = intl.formatDate(new Date(), { format: 'short' });
const relTime = intl.formatRelativeTime(-1, 'day', { format: 'long' });Configure error and warning handlers for debugging and production monitoring.
type OnErrorFn = (
err: MissingTranslationError
| MessageFormatError
| MissingDataError
| InvalidConfigError
| UnsupportedFormatterError
| FormatError
) => void;
type OnWarnFn = (warning: string) => void;Usage Examples:
const intl = createIntl({
locale: 'en-US',
messages: { /* ... */ },
onError: (error) => {
// Log errors to monitoring service
console.error('Intl formatting error:', error.code, error.message);
// Handle specific error types
if (error instanceof MissingTranslationError) {
// Report missing translations
reportMissingTranslation(error.descriptor);
}
},
onWarn: (warning) => {
// Log warnings in development
if (process.env.NODE_ENV === 'development') {
console.warn('Intl warning:', warning);
}
}
});enum IntlErrorCode {
FORMAT_ERROR = 'FORMAT_ERROR',
UNSUPPORTED_FORMATTER = 'UNSUPPORTED_FORMATTER',
INVALID_CONFIG = 'INVALID_CONFIG',
MISSING_DATA = 'MISSING_DATA',
MISSING_TRANSLATION = 'MISSING_TRANSLATION'
}
class IntlError<T extends IntlErrorCode> extends Error {
readonly code: T;
constructor(code: T, message: string, exception?: Error | unknown);
}
class MissingTranslationError extends IntlError<IntlErrorCode.MISSING_TRANSLATION> {
readonly descriptor?: MessageDescriptor;
}
class MessageFormatError extends IntlError<IntlErrorCode.FORMAT_ERROR> {
readonly descriptor?: MessageDescriptor;
readonly locale: string;
}
class InvalidConfigError extends IntlError<IntlErrorCode.INVALID_CONFIG> {}
class MissingDataError extends IntlError<IntlErrorCode.MISSING_DATA> {}
class UnsupportedFormatterError extends IntlError<IntlErrorCode.UNSUPPORTED_FORMATTER> {}