web-i18n-react-intl
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseReact-Intl (FormatJS) Internationalization Patterns
React-Intl(FormatJS)国际化实践模式
Quick Guide: Use react-intl for internationalization with ICU Message Format.for JSX content,FormattedMessagefor string attributes and programmatic use,useIntlfor extractable message descriptors. Wrap app withdefineMessagesand configureIntlProviderfor missing translations. Always include theonErrorcategory in plurals and selects.otherVersion 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,, named constants)import type
(You MUST wrap the application root with and configure locale, messages, and defaultLocale)
IntlProvider(You MUST include the category in ALL plural and select ICU messages - omission causes runtime errors)
other(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 from
createIntl)@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
(必须用包裹应用根组件,并配置locale、messages和defaultLocale)
IntlProvider(在所有复数和选择类型的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 APIs for optimal performance and accurate locale-aware formatting.
IntlCore principles:
- ICU Standard: Use industry-standard ICU Message Format for professional translation workflows
- Dual API: FormattedMessage for JSX content, useIntl for string contexts (attributes, programmatic use)
- Native Intl: Built on browser Intl APIs for accurate locale-specific formatting
- Extractable: defineMessages enables CLI extraction for translation management
<patterns>
React-intl遵循ICU消息格式标准化原则,同时提供声明式和命令式API。翻译采用行业标准的ICU语法,可兼容专业翻译管理系统。该库基于浏览器原生 API构建,以实现最佳性能和准确的语言环境感知格式化。
Intl核心原则:
- ICU标准:使用行业标准的ICU消息格式适配专业翻译工作流
- 双API设计:FormattedMessage用于JSX内容,useIntl用于字符串场景(属性、编程使用)
- 原生Intl依赖:基于浏览器Intl API实现准确的语言环境特定格式化
- 可提取性:defineMessages支持CLI提取以用于翻译管理
<patterns>
Core Patterns
核心实践模式
Pattern 1: IntlProvider Setup
模式1:IntlProvider配置
Wrap your application root with . Configure to distinguish missing translations from actual errors, set for fallback, and define for consistent markup.
IntlProvideronErrordefaultLocaledefaultRichTextElementstypescript
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.
用包裹应用根组件。配置以区分缺失翻译和实际错误,设置作为 fallback,并定义以确保标记一致性。
IntlProvideronErrordefaultLocaledefaultRichTextElementstypescript
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 for rendering translated text directly in JSX elements. Supports ICU syntax for interpolation, pluralization, and rich text.
FormattedMessagetypescript
<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).
使用在JSX元素中直接渲染翻译文本。支持ICU语法实现插值、复数和富文本。
FormattedMessagetypescript
<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 when you need formatted strings for attributes, props, or programmatic use.
useIntltypescript
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或编程场景提供格式化字符串时,使用。
useIntltypescript
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 for CLI extraction and IDE autocomplete.
defineMessagestypescript
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.
使用将相关消息分组,以支持CLI提取和IDE自动补全。
defineMessagestypescript
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 on for , , tags.
defaultRichTextElementsIntlProvider<b><i><br>在消息中使用类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>,
}}
/>通过的配置全局标签处理器,支持、、标签。
IntlProviderdefaultRichTextElements<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 (, ) when you need strings for attributes or programmatic use.
intl.formatDate()intl.formatNumber()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 to in tsconfig.json.
"esnext.intl"compilerOptions.lib通过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.
- Extract messages from source code:
formatjs extract 'src/**/*.{ts,tsx}' --out-file lang/en.json - Send to translation management system (TMS)
- 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提取和编译消息。
- 提取源代码中的消息:
formatjs extract 'src/**/*.{ts,tsx}' --out-file lang/en.json - 发送至翻译管理系统(TMS)
- 编译翻译内容为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 as fallback.
other{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复数语法可处理语言特定规则。务必包含作为 fallback。
other{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 + + for manual control over intl object creation. Useful when you want to memoize the intl instance explicitly.
createIntlcreateIntlCacheRawIntlProvider使用 + + 手动控制intl对象的创建。当需要显式缓存intl实例时非常有用。
createIntlcreateIntlCacheRawIntlProviderAvoid Inline Message Objects
避免内联消息对象
Define messages outside components with rather than passing inline objects to . Inline objects create new references each render, preventing memoization optimizations.
</performance>
defineMessagesFormattedMessage<red_flags>
使用在组件外部定义消息,而不是向传递内联对象。内联对象每次渲染都会创建新引用,无法进行缓存优化。
</performance>
defineMessagesFormattedMessage<red_flags>
RED FLAGS
警示事项
High Priority Issues:
- Missing wrapper - All useIntl and FormattedMessage calls fail without context
IntlProvider - Missing category in plural/select - Runtime error: "other" is REQUIRED in ICU syntax
other - 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 on IntlProvider - No fallback for missing translations
defaultLocale - No handler - Console noise for every missing translation
onError - 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 instead of
{count}for countable items{count, plural, ...} - Missing in plural branches (shows nothing instead of the count value)
#
Gotchas & Edge Cases:
- returns
FormattedMessage, notReactNode- cannot use for HTML attributesstring - returns
formatMessagefor plain values, butstringwhen rich text tag functions are in valuesstring | ReactNode[] - Rich text tag functions receive array, not single element
chunks - with
formatNumberexpects decimal (0.25 for 25%), not percentagestyle: "percent" - value is relative to NOW - negative for past, positive for future
formatRelativeTime - ICU escaping: single quote escapes special characters, double single quote
'produces literal apostrophe'' - Browser Intl support varies - consider polyfills for older browsers
- HOC was removed in v10 - use
injectIntlhook insteaduseIntl - Use prop on IntlProvider to suppress or handle
onWarnwarnings when messages are not pre-compileddefaultRichTextElements
</red_flags>
<critical_reminders>
高优先级问题:
- 缺少包裹——没有上下文的情况下,所有useIntl和FormattedMessage调用都会失败
IntlProvider - 复数/选择类型消息中缺少类别——运行时错误:ICU语法中
other是必填项other - 硬编码语言字符串——使用配置中的命名常量以确保类型安全
- 使用FormattedMessage处理属性——返回ReactNode而非字符串,会破坏placeholder、aria-label、title等属性
中优先级问题:
- IntlProvider上缺少——缺失翻译时无 fallback
defaultLocale - 未配置处理器——每个缺失翻译都会在控制台产生冗余日志
onError - defineMessages中缺少description——翻译人员缺乏上下文以进行准确翻译
常见错误:
- 拼接翻译字符串而非使用带占位符的单个消息(不同语言的词序不同)
- 以编程方式应用英语语法规则(所有格、复数)而非使用ICU语法
- 对可数项使用而非
{count}{count, plural, ...} - 复数分支中缺少(不会显示计数数值)
#
注意事项与边缘情况:
- 返回
FormattedMessage而非ReactNode——不能用于HTML属性string - 对于纯值返回
formatMessage,但当values中包含富文本标签函数时返回stringstring | ReactNode[] - 富文本标签函数接收数组而非单个元素
chunks - 使用
formatNumber时需传入小数(25%对应0.25)而非百分比数值style: "percent" - 的值相对于当前时间——负值表示过去,正值表示未来
formatRelativeTime - ICU转义:单引号用于转义特殊字符,双单引号
'表示字面 apostrophe'' - 浏览器Intl支持存在差异——考虑为旧浏览器引入polyfill
- 高阶组件在v10中已移除——改用
injectIntl钩子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 and configure locale, messages, and defaultLocale)
IntlProvider(You MUST include the category in ALL plural and select ICU messages - omission causes runtime errors)
other(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中的项目约定
(必须用包裹应用根组件,并配置locale、messages和defaultLocale)
IntlProvider(在所有复数和选择类型的ICU消息中必须包含类别——遗漏会导致运行时错误)
other(必须使用命名常量表示语言代码——禁止使用内联语言字符串)
(必须验证React版本兼容性:v7.x支持React 16.6-19,v8+仅支持React 19)
不遵守这些规则会导致运行时错误和国际化功能失效。
</critical_reminders>