web-i18n-react-intl
ICUメッセージ形式で国際化対応されたWebアプリケーションを、React Intlライブラリを用いて多言語対応させるための翻訳作業を効率化するSkill。
📜 元の英語説明(参考)
ICU message format internationalization
🇯🇵 日本人クリエイター向け解説
ICUメッセージ形式で国際化対応されたWebアプリケーションを、React Intlライブラリを用いて多言語対応させるための翻訳作業を効率化するSkill。
※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。
下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o web-i18n-react-intl.zip https://jpskill.com/download/10288.zip && unzip -o web-i18n-react-intl.zip && rm web-i18n-react-intl.zip
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/10288.zip -OutFile "$d\web-i18n-react-intl.zip"; Expand-Archive "$d\web-i18n-react-intl.zip" -DestinationPath $d -Force; ri "$d\web-i18n-react-intl.zip"
完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。
💾 手動でダウンロードしたい(コマンドが難しい人向け)
- 1. 下の青いボタンを押して
web-i18n-react-intl.zipをダウンロード - 2. ZIPファイルをダブルクリックで解凍 →
web-i18n-react-intlフォルダができる - 3. そのフォルダを
C:\Users\あなたの名前\.claude\skills\(Win)または~/.claude/skills/(Mac)へ移動 - 4. Claude Code を再起動
⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。
🎯 このSkillでできること
下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。
📦 インストール方法 (3ステップ)
- 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
- 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
- 3. 展開してできたフォルダを、ホームフォルダの
.claude/skills/に置く- · macOS / Linux:
~/.claude/skills/ - · Windows:
%USERPROFILE%\.claude\skills\
- · macOS / Linux:
Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。
詳しい使い方ガイドを見る →- 最終更新
- 2026-05-18
- 取得日時
- 2026-05-18
- 同梱ファイル
- 1
📖 Skill本文(日本語訳)
※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。
React-Intl (FormatJS) 国際化パターン
クイックガイド: ICU Message Format を使用した国際化には react-intl を使用します。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>
重要: この Skill を使用する前に
すべてのコードは CLAUDE.md のプロジェクト規約に従う必要があります (kebab-case、名前付きエクスポート、インポート順序、
import type、名前付き定数)
(アプリケーションのルートを IntlProvider でラップし、ロケール、メッセージ、および 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 拡張によるタイプセーフな i18n を構築する場合
カバーする主なパターン:
- エラー処理とデフォルトのリッチテキスト要素を使用した IntlProvider の設定
- FormattedMessage vs useIntl: 宣言的な JSX vs 命令的な文字列
- 静的メッセージ抽出のための defineMessages
- ICU Message Format 構文 (複数形、選択、序数、リッチテキスト)
- 日付、時刻、数値、通貨、相対時間、およびリストのフォーマット
- タイプセーフなメッセージ ID のための TypeScript 統合
- 動的インポートによるロケールデータの遅延ロード
使用しない場面:
- ビルトイン i18n を備えた SSR フレームワーク (より優れた SSR 統合のために、フレームワークの i18n ソリューションを使用してください)
- シンプルな単一ロケールアプリケーション (i18n の複雑さをスキップしてください)
- React コンテキストなしのサーバーサイドレンダリング (
@formatjs/intlからcreateIntlを使用してください)
詳細なリソース:
- examples/core.md - IntlProvider の設定、FormattedMessage, useIntl, defineMessages, TypeScript 統合、遅延ロード
- examples/formatting.md - 日付、時刻、数値、通貨、相対時間、およびリストのフォーマット
- examples/pluralization.md - 複数形、序数、選択、ネストされた ICU パターン
- reference.md - 意思決定フレームワーク、ICU 構文クイックリファレンス、API テーブル、アンチパターン
<philosophy>
哲学
React-intl は、宣言型 API と命令型 API の両方を備えた ICU Message Format 標準化の原則に従います。翻訳は業界標準の ICU 構文を使用しており、プロの翻訳管理システムとの互換性を実現します。このライブラリは、最適なパフォーマンスと正確なロケール対応フォーマットのために、ブラウザネイティブの Intl API 上に構築されています。
コア原則:
- ICU 標準: プロの翻訳ワークフローには、業界標準の ICU Message Format を使用します
- デュアル API: JSX コンテンツには FormattedMessage、文字列コンテキスト (属性、プログラムによる使用) には useIntl を使用します
- ネイティブ Intl: 正確なロケール固有のフォーマットのために、ブラウザの Intl API 上に構築されています
- 抽出可能: defineMessages により、翻訳管理のための CLI 抽出が可能になります
</philosophy>
<patterns>
コアパターン
パターン 1: IntlProvider の設定
アプリケーションのルートを IntlProvider でラップします。翻訳が見つからない場合と実際のエラーを区別するために onError を設定し、フォールバック用に defaultLocale を設定し、一貫したマークアップのために defaultRichTextElements を定義します。
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 はフォールバックを提供し、defaultRichTextElements は一貫したマークアップを保証します
ロケール設定、遅延ロード、およびアプリ統合を含む完全な設定については、examples/core.md を参照してください。
パターン 2: FormattedMessage (宣言的な JSX)
JSX 要素で翻訳されたテキストを直接レンダリングするには、FormattedMessage を使用します。補間、複数形、およびリッチテキストの ICU 構文をサポートします。
<FormattedMessage
id="greeting.unread"
defaultMessage="{count, plural, =0 {No messages} one {# message} other {# messages}}"
values={{ count: unreadCount }}
/>
使用する場面: JSX で直接レンダリングされるテキストコンテンツ、埋め込みフォーマットのリッチテキスト。
使用しない場面: placeholder、aria-label、title などの文字列属性 (代わりに useIntl を使用してください)。
パターン 3: useIntl フック (命令的な文字列)
属性、プロパティ、またはプログラムによる使用のためにフォーマットされた文字列が必要な場合は、useIntl を使用します。
const intl = useIntl();
const placeholder = intl.formatMessage({
id: "search.placeholder",
defaultMessage: "Search products...",
});
<input placeholder={placeholder} aria-label={ariaLabel} />
使用する場面: 入力プレースホルダー、ARIA ラベル、ドキュメントタイトル、サードパーティコンポーネントのプロパティ、フォーマットされた値に基づく条件付きロジック。
パターン 4: 静的抽出のための defineMessages
(原文はここで切り詰められています)
📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開
React-Intl (FormatJS) Internationalization Patterns
Quick Guide: Use react-intl for internationalization with ICU Message Format.
FormattedMessagefor JSX content,useIntlfor string attributes and programmatic use,defineMessagesfor extractable message descriptors. Wrap app withIntlProviderand configureonErrorfor missing translations. Always include theothercategory 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>
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
createIntlfrom@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>
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:
- 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
</philosophy>
<patterns>
Core Patterns
Pattern 1: IntlProvider Setup
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.
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.
Pattern 2: FormattedMessage (Declarative JSX)
Use FormattedMessage for rendering translated text directly in JSX elements. Supports ICU syntax for interpolation, pluralization, and rich text.
<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).
Pattern 3: useIntl Hook (Imperative Strings)
Use useIntl when you need formatted strings for attributes, props, or programmatic use.
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.
Pattern 4: defineMessages for Static Extraction
Group related messages with defineMessages for CLI extraction and IDE autocomplete.
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.
Pattern 5: Rich Text Formatting
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.
<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.
Pattern 6: Formatting Components
Locale-aware formatting for dates, numbers, currency, relative time, and lists.
<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.
Pattern 7: TypeScript Integration
Enable type-safe message IDs with TypeScript module augmentation.
// 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.
Pattern 8: Message Extraction Workflow
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.
Pattern 9: ICU Pluralization
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>
Performance
Message Compilation (AST Pre-parsing)
Compile messages to AST at build time to skip runtime parsing. Impact: 30-50% faster initial render for large catalogs.
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.
RawIntlProvider with createIntl
Use createIntl + createIntlCache + RawIntlProvider for manual control over intl object creation. Useful when you want to memoize the intl instance explicitly.
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>
RED FLAGS
High Priority Issues:
- Missing
IntlProviderwrapper - All useIntl and FormattedMessage calls fail without context - Missing
othercategory 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
defaultLocaleon IntlProvider - No fallback for missing translations - No
onErrorhandler - 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:
FormattedMessagereturnsReactNode, notstring- cannot use for HTML attributesformatMessagereturnsstringfor plain values, butstring | ReactNode[]when rich text tag functions are in values- Rich text tag functions receive
chunksarray, not single element formatNumberwithstyle: "percent"expects decimal (0.25 for 25%), not percentageformatRelativeTimevalue 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
injectIntlHOC was removed in v10 - useuseIntlhook instead- Use
onWarnprop on IntlProvider to suppress or handledefaultRichTextElementswarnings when messages are not pre-compiled
</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>