web-i18n-react-intl

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

React-Intl (FormatJS) Internationalization Patterns

React-Intl(FormatJS)国际化实践模式

Quick Guide: Use react-intl for internationalization with ICU Message Format.
FormattedMessage
for JSX content,
useIntl
for string attributes and programmatic use,
defineMessages
for extractable message descriptors. Wrap app with
IntlProvider
and configure
onError
for missing translations. Always include the
other
category in plurals and selects.
Version Note: react-intl v7.x supports React 16.6+/17/18/19. v8+ requires React 19 only (React 18 support dropped). Current latest: v10.x.

<critical_requirements>
快速指南: 使用react-intl结合ICU消息格式实现国际化。在JSX内容中使用
FormattedMessage
,在字符串属性和编程场景中使用
useIntl
,使用
defineMessages
定义可提取的消息描述符。用
IntlProvider
包裹应用,并配置
onError
处理缺失的翻译。在复数和选择类型的消息中务必包含
other
类别。
版本说明: react-intl v7.x支持React 16.6+/17/18/19。v8+仅支持React 19(不再支持React 18)。当前最新版本:v10.x。

<critical_requirements>

CRITICAL: Before Using This Skill

重要须知:使用此技能前需遵守

All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering,
import type
, named constants)
(You MUST wrap the application root with
IntlProvider
and configure locale, messages, and defaultLocale)
(You MUST include the
other
category in ALL plural and select ICU messages - omission causes runtime errors)
(You MUST use named constants for locale codes - NO inline locale strings)
(You MUST verify React version compatibility: v7.x supports React 16.6-19, v8+ requires React 19 only)
</critical_requirements>

Auto-detection: react-intl, FormatJS, FormattedMessage, useIntl, IntlProvider, defineMessages, ICU message format, formatMessage, FormattedDate, FormattedNumber, FormattedRelativeTime
When to use:
  • Implementing internationalization in React applications
  • Rendering localized messages with ICU syntax (interpolation, pluralization, select)
  • Formatting dates, numbers, currency, and relative time per locale
  • Extracting and compiling translation messages for TMS workflows
  • Building type-safe i18n with TypeScript augmentation
Key patterns covered:
  • IntlProvider setup with error handling and default rich text elements
  • FormattedMessage vs useIntl: declarative JSX vs imperative strings
  • defineMessages for static message extraction
  • ICU Message Format syntax (plurals, select, ordinals, rich text)
  • Date, time, number, currency, relative time, and list formatting
  • TypeScript integration for type-safe message IDs
  • Lazy loading locale data with dynamic imports
When NOT to use:
  • SSR frameworks with built-in i18n (use the framework's i18n solution for better SSR integration)
  • Simple single-locale applications (skip i18n complexity)
  • Server-side rendering without React context (use
    createIntl
    from
    @formatjs/intl
    )
Detailed Resources:
  • examples/core.md - IntlProvider setup, FormattedMessage, useIntl, defineMessages, TypeScript integration, lazy loading
  • examples/formatting.md - Date, time, number, currency, relative time, and list formatting
  • examples/pluralization.md - Plural, ordinal, select, nested ICU patterns
  • reference.md - Decision frameworks, ICU syntax quick reference, API tables, anti-patterns

<philosophy>
所有代码必须遵循CLAUDE.md中的项目约定(短横线命名法、命名导出、导入顺序、
import type
、命名常量)
(必须用
IntlProvider
包裹应用根组件,并配置locale、messages和defaultLocale)
(在所有复数和选择类型的ICU消息中必须包含
other
类别——遗漏会导致运行时错误)
(必须使用命名常量表示语言代码——禁止使用内联语言字符串)
(必须验证React版本兼容性:v7.x支持React 16.6-19,v8+仅支持React 19)
</critical_requirements>

自动检测关键词: react-intl, FormatJS, FormattedMessage, useIntl, IntlProvider, defineMessages, ICU message format, formatMessage, FormattedDate, FormattedNumber, FormattedRelativeTime
适用场景:
  • 在React应用中实现国际化
  • 使用ICU语法渲染本地化消息(插值、复数、选择)
  • 根据语言环境格式化日期、数字、货币和相对时间
  • 提取并编译翻译消息以适配翻译管理系统(TMS)工作流
  • 通过TypeScript增强构建类型安全的国际化方案
涵盖的核心实践模式:
  • 带错误处理和默认富文本元素的IntlProvider配置
  • FormattedMessage与useIntl的对比:声明式JSX vs 命令式字符串
  • 使用defineMessages进行静态消息提取
  • ICU消息格式语法(复数、选择、序数、富文本)
  • 日期、时间、数字、货币、相对时间和列表格式化
  • TypeScript集成实现类型安全的消息ID
  • 动态导入实现语言环境数据懒加载
不适用场景:
  • 内置国际化功能的SSR框架(优先使用框架自带的国际化方案以获得更好的SSR集成)
  • 简单的单语言应用(无需引入国际化复杂度)
  • 无React上下文的服务端渲染(使用
    @formatjs/intl
    中的
    createIntl
详细资源:
  • examples/core.md - IntlProvider配置、FormattedMessage、useIntl、defineMessages、TypeScript集成、懒加载
  • examples/formatting.md - 日期、时间、数字、货币、相对时间和列表格式化
  • examples/pluralization.md - 复数、序数、选择、嵌套ICU模式
  • reference.md - 决策框架、ICU语法速查、API表格、反模式

<philosophy>

Philosophy

设计理念

React-intl follows the principle of ICU Message Format standardization with both declarative and imperative APIs. Translations use industry-standard ICU syntax enabling compatibility with professional translation management systems. The library is built on browser-native
Intl
APIs for optimal performance and accurate locale-aware formatting.
Core principles:
  1. ICU Standard: Use industry-standard ICU Message Format for professional translation workflows
  2. Dual API: FormattedMessage for JSX content, useIntl for string contexts (attributes, programmatic use)
  3. Native Intl: Built on browser Intl APIs for accurate locale-specific formatting
  4. Extractable: defineMessages enables CLI extraction for translation management
</philosophy>
<patterns>
React-intl遵循ICU消息格式标准化原则,同时提供声明式和命令式API。翻译采用行业标准的ICU语法,可兼容专业翻译管理系统。该库基于浏览器原生
Intl
API构建,以实现最佳性能和准确的语言环境感知格式化。
核心原则:
  1. ICU标准:使用行业标准的ICU消息格式适配专业翻译工作流
  2. 双API设计:FormattedMessage用于JSX内容,useIntl用于字符串场景(属性、编程使用)
  3. 原生Intl依赖:基于浏览器Intl API实现准确的语言环境特定格式化
  4. 可提取性:defineMessages支持CLI提取以用于翻译管理
</philosophy>
<patterns>

Core Patterns

核心实践模式

Pattern 1: IntlProvider Setup

模式1:IntlProvider配置

Wrap your application root with
IntlProvider
. Configure
onError
to distinguish missing translations from actual errors, set
defaultLocale
for fallback, and define
defaultRichTextElements
for consistent markup.
typescript
export function AppIntlProvider({ children, locale, messages }: Props) {
  return (
    <IntlProvider
      locale={locale}
      defaultLocale={DEFAULT_LOCALE}
      messages={messages}
      defaultRichTextElements={DEFAULT_RICH_TEXT_ELEMENTS}
      onError={(err) => {
        if (err.code === "MISSING_TRANSLATION") {
          console.warn(`Missing translation: ${err.message}`);
          return;
        }
        throw err;
      }}
    >
      {children}
    </IntlProvider>
  );
}
Why good: custom onError distinguishes missing translations from actual errors, defaultLocale provides fallback, defaultRichTextElements ensure consistent markup
See examples/core.md for full setup with locale config, lazy loading, and app integration.

IntlProvider
包裹应用根组件。配置
onError
以区分缺失翻译和实际错误,设置
defaultLocale
作为 fallback,并定义
defaultRichTextElements
以确保标记一致性。
typescript
export function AppIntlProvider({ children, locale, messages }: Props) {
  return (
    <IntlProvider
      locale={locale}
      defaultLocale={DEFAULT_LOCALE}
      messages={messages}
      defaultRichTextElements={DEFAULT_RICH_TEXT_ELEMENTS}
      onError={(err) => {
        if (err.code === "MISSING_TRANSLATION") {
          console.warn(`Missing translation: ${err.message}`);
          return;
        }
        throw err;
      }}
    >
      {children}
    </IntlProvider>
  );
}
优势: 自定义onError可区分缺失翻译和实际错误,defaultLocale提供 fallback,defaultRichTextElements确保标记一致性
查看examples/core.md获取包含语言环境配置、懒加载和应用集成的完整配置示例。

Pattern 2: FormattedMessage (Declarative JSX)

模式2:FormattedMessage(声明式JSX)

Use
FormattedMessage
for rendering translated text directly in JSX elements. Supports ICU syntax for interpolation, pluralization, and rich text.
typescript
<FormattedMessage
  id="greeting.unread"
  defaultMessage="{count, plural, =0 {No messages} one {# message} other {# messages}}"
  values={{ count: unreadCount }}
/>
When to use: Text content rendered directly in JSX, rich text with embedded formatting.
When not to use: String attributes like placeholder, aria-label, title (use useIntl instead).

使用
FormattedMessage
在JSX元素中直接渲染翻译文本。支持ICU语法实现插值、复数和富文本。
typescript
<FormattedMessage
  id="greeting.unread"
  defaultMessage="{count, plural, =0 {No messages} one {# message} other {# messages}}"
  values={{ count: unreadCount }}
/>
适用场景: 直接在JSX中渲染的文本内容,带嵌入式格式的富文本。
不适用场景: 字符串属性如placeholder、aria-label、title(改用useIntl)。

Pattern 3: useIntl Hook (Imperative Strings)

模式3:useIntl钩子(命令式字符串)

Use
useIntl
when you need formatted strings for attributes, props, or programmatic use.
typescript
const intl = useIntl();
const placeholder = intl.formatMessage({
  id: "search.placeholder",
  defaultMessage: "Search products...",
});

<input placeholder={placeholder} aria-label={ariaLabel} />
When to use: Input placeholders, ARIA labels, document titles, third-party component props, conditional logic based on formatted values.

当需要为属性、props或编程场景提供格式化字符串时,使用
useIntl
typescript
const intl = useIntl();
const placeholder = intl.formatMessage({
  id: "search.placeholder",
  defaultMessage: "Search products...",
});

<input placeholder={placeholder} aria-label={ariaLabel} />
适用场景: 输入框占位符、ARIA标签、文档标题、第三方组件props、基于格式化值的条件逻辑。

Pattern 4: defineMessages for Static Extraction

模式4:defineMessages用于静态提取

Group related messages with
defineMessages
for CLI extraction and IDE autocomplete.
typescript
export const productMessages = defineMessages({
  title: {
    id: "product.title",
    defaultMessage: "Product Details",
    description: "Page title for product detail page",
  },
  reviewCount: {
    id: "product.reviewCount",
    defaultMessage:
      "{count, plural, =0 {No reviews} one {# review} other {# reviews}}",
    description: "Number of product reviews with pluralization",
  },
});
Why good: centralizes related messages, descriptions provide translator context, CLI extracts these automatically, IDE autocomplete for references
See examples/core.md for usage patterns with FormattedMessage and useIntl.

使用
defineMessages
将相关消息分组,以支持CLI提取和IDE自动补全。
typescript
export const productMessages = defineMessages({
  title: {
    id: "product.title",
    defaultMessage: "Product Details",
    description: "Page title for product detail page",
  },
  reviewCount: {
    id: "product.reviewCount",
    defaultMessage:
      "{count, plural, =0 {No reviews} one {# review} other {# reviews}}",
    description: "Number of product reviews with pluralization",
  },
});
优势: 集中管理相关消息,描述信息为翻译人员提供上下文,CLI可自动提取,IDE支持引用自动补全
查看examples/core.md获取与FormattedMessage和useIntl配合使用的实践模式。

Pattern 5: Rich Text Formatting

模式5:富文本格式化

Use XML-like tags in messages for embedded markup. Translators can reorder tags per language grammar while the complete sentence stays in one translation unit.
typescript
<FormattedMessage
  id="terms.notice"
  defaultMessage="By signing up, you agree to our <terms>Terms</terms> and <privacy>Privacy Policy</privacy>."
  values={{
    terms: (chunks) => <a href="/terms">{chunks}</a>,
    privacy: (chunks) => <a href="/privacy">{chunks}</a>,
  }}
/>
Configure global tag handlers via
defaultRichTextElements
on
IntlProvider
for
<b>
,
<i>
,
<br>
tags.

在消息中使用类XML标签实现嵌入式标记。翻译人员可根据语言语法重新排列标签,同时保持完整句子在单个翻译单元中。
typescript
<FormattedMessage
  id="terms.notice"
  defaultMessage="By signing up, you agree to our <terms>Terms</terms> and <privacy>Privacy Policy</privacy>."
  values={{
    terms: (chunks) => <a href="/terms">{chunks}</a>,
    privacy: (chunks) => <a href="/privacy">{chunks}</a>,
  }}
/>
通过
IntlProvider
defaultRichTextElements
配置全局标签处理器,支持
<b>
<i>
<br>
标签。

Pattern 6: Formatting Components

模式6:格式化组件

Locale-aware formatting for dates, numbers, currency, relative time, and lists.
typescript
<FormattedDate value={date} year="numeric" month="long" day="numeric" />
// en-US: "January 15, 2024" | de-DE: "15. Januar 2024"

<FormattedNumber value={amount} style="currency" currency={currency} />
// en-US: "$1,234.56" | de-DE: "1.234,56 EUR"

<FormattedList type="conjunction" value={names} />
// en: "Alice, Bob, and Charlie" | es: "Alice, Bob y Charlie"
Use imperative equivalents (
intl.formatDate()
,
intl.formatNumber()
) when you need strings for attributes or programmatic use.
See examples/formatting.md for comprehensive date/time, number, currency, relative time, and list examples.

支持语言环境感知的日期、数字、货币、相对时间和列表格式化。
typescript
<FormattedDate value={date} year="numeric" month="long" day="numeric" />
// en-US: "January 15, 2024" | de-DE: "15. Januar 2024"

<FormattedNumber value={amount} style="currency" currency={currency} />
// en-US: "$1,234.56" | de-DE: "1.234,56 EUR"

<FormattedList type="conjunction" value={names} />
// en: "Alice, Bob, and Charlie" | es: "Alice, Bob y Charlie"
当需要为属性或编程场景提供字符串时,使用命令式等效方法(
intl.formatDate()
intl.formatNumber()
)。
查看examples/formatting.md获取全面的日期/时间、数字、货币、相对时间和列表示例。

Pattern 7: TypeScript Integration

模式7:TypeScript集成

Enable type-safe message IDs with TypeScript module augmentation.
typescript
// src/types/intl.d.ts
import type messages from "../lang/en.json";

type MessageIds = keyof typeof messages;

declare global {
  namespace FormatjsIntl {
    interface Message {
      ids: MessageIds;
    }
  }
}
Typos in message IDs become compile-time errors. Add
"esnext.intl"
to
compilerOptions.lib
in tsconfig.json.

通过TypeScript模块增强实现类型安全的消息ID。
typescript
// src/types/intl.d.ts
import type messages from "../lang/en.json";

type MessageIds = keyof typeof messages;

declare global {
  namespace FormatjsIntl {
    interface Message {
      ids: MessageIds;
    }
  }
}
消息ID中的拼写错误会成为编译时错误。在tsconfig.json的
compilerOptions.lib
中添加
"esnext.intl"

Pattern 8: Message Extraction Workflow

模式8:消息提取工作流

Use FormatJS CLI for extracting and compiling messages.
  1. Extract messages from source code:
    formatjs extract 'src/**/*.{ts,tsx}' --out-file lang/en.json
  2. Send to translation management system (TMS)
  3. Compile translations to AST format:
    formatjs compile lang/en.json --out-file compiled/en.json --ast
Why compile to AST: 30-50% faster initial render for large message catalogs - skips runtime parsing.

使用FormatJS CLI提取和编译消息。
  1. 提取源代码中的消息:
    formatjs extract 'src/**/*.{ts,tsx}' --out-file lang/en.json
  2. 发送至翻译管理系统(TMS)
  3. 编译翻译内容为AST格式:
    formatjs compile lang/en.json --out-file compiled/en.json --ast
编译为AST的优势: 对于大型消息目录,初始渲染速度提升30-50%——跳过运行时解析。

Pattern 9: ICU Pluralization

模式9:ICU复数处理

ICU plural syntax handles language-specific rules. Always include
other
as fallback.
{count, plural, =0 {No items} one {# item} other {# items}}
{position, selectordinal, one {#st} two {#nd} few {#rd} other {#th}}
{gender, select, male {He} female {She} other {They}} liked your post.
Different languages have different plural categories (English: one/other, Russian: one/few/many/other, Arabic: zero/one/two/few/many/other).
See examples/pluralization.md for nested patterns, ordinals, select, and language-specific examples.
</patterns>
<performance>
ICU复数语法可处理语言特定规则。务必包含
other
作为 fallback。
{count, plural, =0 {No items} one {# item} other {# items}}
{position, selectordinal, one {#st} two {#nd} few {#rd} other {#th}}
{gender, select, male {He} female {She} other {They}} liked your post.
不同语言有不同的复数类别(英语:one/other,俄语:one/few/many/other,阿拉伯语:zero/one/two/few/many/other)。
查看examples/pluralization.md获取嵌套模式、序数、选择和语言特定示例。
</patterns>
<performance>

Performance

性能优化

Message Compilation (AST Pre-parsing)

消息编译(AST预解析)

Compile messages to AST at build time to skip runtime parsing. Impact: 30-50% faster initial render for large catalogs.
在构建时将消息编译为AST,以跳过运行时解析。影响:大型目录初始渲染速度提升30-50%。

Lazy Loading Locale Data

语言环境数据懒加载

Use dynamic imports to load only the current locale's messages. Cache loaded messages to prevent duplicate fetches. See examples/core.md for implementation.
使用动态导入仅加载当前语言环境的消息。缓存已加载的消息以避免重复请求。查看examples/core.md获取实现方案。

RawIntlProvider with createIntl

使用createIntl搭配RawIntlProvider

Use
createIntl
+
createIntlCache
+
RawIntlProvider
for manual control over intl object creation. Useful when you want to memoize the intl instance explicitly.
使用
createIntl
+
createIntlCache
+
RawIntlProvider
手动控制intl对象的创建。当需要显式缓存intl实例时非常有用。

Avoid Inline Message Objects

避免内联消息对象

Define messages outside components with
defineMessages
rather than passing inline objects to
FormattedMessage
. Inline objects create new references each render, preventing memoization optimizations.
</performance>
<red_flags>
使用
defineMessages
在组件外部定义消息,而不是向
FormattedMessage
传递内联对象。内联对象每次渲染都会创建新引用,无法进行缓存优化。
</performance>
<red_flags>

RED FLAGS

警示事项

High Priority Issues:
  • Missing
    IntlProvider
    wrapper
    - All useIntl and FormattedMessage calls fail without context
  • Missing
    other
    category in plural/select
    - Runtime error: "other" is REQUIRED in ICU syntax
  • Hardcoded locale strings - Use named constants from config for type safety
  • Using FormattedMessage for attributes - Returns ReactNode, not string; breaks placeholder, aria-label, title
Medium Priority Issues:
  • Missing
    defaultLocale
    on IntlProvider
    - No fallback for missing translations
  • No
    onError
    handler
    - Console noise for every missing translation
  • Missing description in defineMessages - Translators lack context for accurate translation
Common Mistakes:
  • Concatenating translated strings instead of single message with placeholders (word order varies by language)
  • Applying English grammar rules programmatically (possessives, plurals) instead of using ICU syntax
  • Using
    {count}
    instead of
    {count, plural, ...}
    for countable items
  • Missing
    #
    in plural branches (shows nothing instead of the count value)
Gotchas & Edge Cases:
  • FormattedMessage
    returns
    ReactNode
    , not
    string
    - cannot use for HTML attributes
  • formatMessage
    returns
    string
    for plain values, but
    string | ReactNode[]
    when rich text tag functions are in values
  • Rich text tag functions receive
    chunks
    array, not single element
  • formatNumber
    with
    style: "percent"
    expects decimal (0.25 for 25%), not percentage
  • formatRelativeTime
    value is relative to NOW - negative for past, positive for future
  • ICU escaping: single quote
    '
    escapes special characters, double single quote
    ''
    produces literal apostrophe
  • Browser Intl support varies - consider polyfills for older browsers
  • injectIntl
    HOC was removed in v10 - use
    useIntl
    hook instead
  • Use
    onWarn
    prop on IntlProvider to suppress or handle
    defaultRichTextElements
    warnings when messages are not pre-compiled
</red_flags>

<critical_reminders>
高优先级问题:
  • 缺少
    IntlProvider
    包裹
    ——没有上下文的情况下,所有useIntl和FormattedMessage调用都会失败
  • 复数/选择类型消息中缺少
    other
    类别
    ——运行时错误:ICU语法中
    other
    是必填项
  • 硬编码语言字符串——使用配置中的命名常量以确保类型安全
  • 使用FormattedMessage处理属性——返回ReactNode而非字符串,会破坏placeholder、aria-label、title等属性
中优先级问题:
  • IntlProvider上缺少
    defaultLocale
    ——缺失翻译时无 fallback
  • 未配置
    onError
    处理器
    ——每个缺失翻译都会在控制台产生冗余日志
  • defineMessages中缺少description——翻译人员缺乏上下文以进行准确翻译
常见错误:
  • 拼接翻译字符串而非使用带占位符的单个消息(不同语言的词序不同)
  • 以编程方式应用英语语法规则(所有格、复数)而非使用ICU语法
  • 对可数项使用
    {count}
    而非
    {count, plural, ...}
  • 复数分支中缺少
    #
    (不会显示计数数值)
注意事项与边缘情况:
  • FormattedMessage
    返回
    ReactNode
    而非
    string
    ——不能用于HTML属性
  • formatMessage
    对于纯值返回
    string
    ,但当values中包含富文本标签函数时返回
    string | ReactNode[]
  • 富文本标签函数接收
    chunks
    数组而非单个元素
  • formatNumber
    使用
    style: "percent"
    时需传入小数(25%对应0.25)而非百分比数值
  • formatRelativeTime
    的值相对于当前时间——负值表示过去,正值表示未来
  • ICU转义:单引号
    '
    用于转义特殊字符,双单引号
    ''
    表示字面 apostrophe
  • 浏览器Intl支持存在差异——考虑为旧浏览器引入polyfill
  • injectIntl
    高阶组件在v10中已移除——改用
    useIntl
    钩子
  • 当消息未预编译时,使用IntlProvider的
    onWarn
    属性抑制或处理
    defaultRichTextElements
    警告
</red_flags>

<critical_reminders>

CRITICAL REMINDERS

重要提醒

All code must follow project conventions in CLAUDE.md
(You MUST wrap the application root with
IntlProvider
and configure locale, messages, and defaultLocale)
(You MUST include the
other
category in ALL plural and select ICU messages - omission causes runtime errors)
(You MUST use named constants for locale codes - NO inline locale strings)
(You MUST verify React version compatibility: v7.x supports React 16.6-19, v8+ requires React 19 only)
Failure to follow these rules will cause runtime errors and broken internationalization.
</critical_reminders>
所有代码必须遵循CLAUDE.md中的项目约定
(必须用
IntlProvider
包裹应用根组件,并配置locale、messages和defaultLocale)
(在所有复数和选择类型的ICU消息中必须包含
other
类别——遗漏会导致运行时错误)
(必须使用命名常量表示语言代码——禁止使用内联语言字符串)
(必须验证React版本兼容性:v7.x支持React 16.6-19,v8+仅支持React 19)
不遵守这些规则会导致运行时错误和国际化功能失效。
</critical_reminders>