i18n について
i18n は、アプリケーションの国際化開発向けリファレンススキルです。React の i18next パターンと Next.js の next-intl を紹介し、書式設定、翻訳ファイルの構成、よくある問題も解説します。
主な機能
- 01React 向け i18next パターン
- 02Next.js 向け next-intl 設定
- 03Intl による日付と数値の書式設定
- 04ICU メッセージ形式の例
- 05翻訳ファイルの構成
活用シーン
- 01React インターフェースに翻訳を追加する
- 02Next.js アプリでローカライズを設定する
- 03国際化の実装を確認する
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ claude-dev-suite/ claude-dev-suite --skill i18nインストール後、Claude Code で/i18nを入力して読み込まれたか確認します。
詳細
国際化(i18n)
i18next(React — 推奨)
// i18n.ts
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import Backend from 'i18next-http-backend';
import LanguageDetector from 'i18next-browser-languagedetector';
i18n
.use(Backend)
.use(LanguageDetector)
.use(initReactI18next)
.init({
fallbackLng: 'en',
ns: ['common', 'auth'],
defaultNS: 'common',
interpolation: { escapeValue: false },
});
export default i18n;
// Usage in components
import { useTranslation } from 'react-i18next';
function Welcome() {
const { t } = useTranslation();
return (
<>
<h1>{t('welcome', { name: 'John' })}</h1>
<p>{t('items_count', { count: 5 })}</p>
</>
);
}
翻訳ファイル
// locales/en/common.json
{
"welcome": "Welcome, {{name}}!",
"items_count_one": "{{count}} item",
"items_count_other": "{{count}} items"
}
// locales/it/common.json
{
"welcome": "Benvenuto, {{name}}!",
"items_count_one": "{{count}} elemento",
"items_count_other": "{{count}} elementi"
}
next-intl(Next.js)
// i18n/request.ts
import { getRequestConfig } from 'next-intl/server';
export default getRequestConfig(async ({ locale }) => ({
messages: (await import(`../messages/${locale}.json`)).default,
}));
import { useTranslations } from 'next-intl';
function Page() {
const t = useTranslations('HomePage');
return <h1>{t('title')}</h1>;
}
日付と数値のフォーマット
// Use Intl API (built-in, no library needed)
const dateFormatter = new Intl.DateTimeFormat('de-DE', {
year: 'numeric', month: 'long', day: 'numeric',
});
dateFormatter.format(new Date()); // "5. Marz 2026"
const currencyFormatter = new Intl.NumberFormat('en-US', {
style: 'currency', currency: 'USD',
});
currencyFormatter.format(42.5); // "$42.50"
// Relative time
const rtf = new Intl.RelativeTimeFormat('en', { numeric: 'auto' });
rtf.format(-1, 'day'); // "yesterday"
ICU メッセージ形式
{
"greeting": "{gender, select, male {Mr.} female {Ms.} other {Mx.}} {name}",
"notifications": "{count, plural, =0 {No notifications} one {# notification} other {# notifications}}"
}
翻訳ファイルの構造
locales/
├── en/
│ ├── common.json # Shared strings
│ ├── auth.json # Auth-specific
│ └── errors.json # Error messages
├── it/
│ ├── common.json
│ ├── auth.json
│ └── errors.json
アンチパターン
| アンチパターン | 修正方法 |
|---|---|
| UI 内に文字列をハードコードする | ユーザーに表示するすべてのテキストを翻訳ファイルに取り出します |
| 文章の文字列連結 | 補間({{name}})または ICU 形式を使用します |
| 複数形の処理を手動で実装する | 組み込みの複数形ルール(_one、_other)を使用します |
| 文字列操作による日付のフォーマット | Intl.DateTimeFormat を使用します |
| フォールバック言語がない | 常に fallbackLng を設定します |
| 巨大な単一の翻訳ファイル | 名前空間(common、auth、errors)ごとに分割します |
本番環境向けチェックリスト
- ユーザーに表示するすべての文字列を外部化する
- サポートするすべての言語に複数形ルールを設定する
-
IntlAPI を使用して日付と数値をフォーマットする - RTL レイアウトをサポートする(該当する場合)
- 言語を検出する(ブラウザー、ユーザー設定)
- 翻訳者と連携する翻訳ワークフローを用意する
- CI で欠落しているキーを検出する
コメント
Markdown 対応