Claude Codeで多言語対応(i18n)を効率的に実装する方法
Claude Codeを活用してReact・Next.jsアプリの国際化(i18n)を効率的に実装する方法を解説。翻訳ファイル管理や動的ロケール切替の実例を紹介します。
多言語対応でClaude Codeが活きる場面
国際化(i18n)の実装は、翻訳ファイルの管理、ロケール切り替え、日付・数値のフォーマット、RTL対応など多岐にわたります。Claude Codeはこれらの作業を一括で処理し、翻訳漏れのチェックまで行えます。
Next.jsでのi18n基盤構築
> Next.js App Routerでnext-intlを使った多言語対応を設定して。
> 日本語と英語をサポートして。URLパスにロケールを含める形式で。
ディレクトリ構成
src/
messages/
ja.json
en.json
app/
[locale]/
layout.tsx
page.tsx
i18n/
request.ts
routing.ts
ルーティング設定
// src/i18n/routing.ts
import { defineRouting } from 'next-intl/routing';
export const routing = defineRouting({
locales: ['ja', 'en'],
defaultLocale: 'ja',
pathnames: {
'/': '/',
'/about': {
ja: '/about',
en: '/about',
},
'/blog': {
ja: '/blog',
en: '/blog',
},
},
});
// src/i18n/request.ts
import { getRequestConfig } from 'next-intl/server';
import { routing } from './routing';
export default getRequestConfig(async ({ requestLocale }) => {
let locale = await requestLocale;
if (!locale || !routing.locales.includes(locale as 'ja' | 'en')) {
locale = routing.defaultLocale;
}
return {
locale,
messages: (await import(`../messages/${locale}.json`)).default,
};
});
翻訳ファイル
// src/messages/ja.json
{
"common": {
"siteName": "マイアプリ",
"navigation": {
"home": "ホーム",
"about": "概要",
"blog": "ブログ",
"contact": "お問い合わせ"
},
"footer": {
"copyright": "© {year} マイアプリ. All rights reserved."
}
},
"home": {
"hero": {
"title": "最高のサービスを提供します",
"subtitle": "{count, plural, =0 {ユーザーはまだいません} one {# 人のユーザー} other {# 人のユーザー}}が利用中"
}
}
}
// src/messages/en.json
{
"common": {
"siteName": "MyApp",
"navigation": {
"home": "Home",
"about": "About",
"blog": "Blog",
"contact": "Contact"
},
"footer": {
"copyright": "© {year} MyApp. All rights reserved."
}
},
"home": {
"hero": {
"title": "We provide the best service",
"subtitle": "{count, plural, =0 {No users yet} one {# user} other {# users}} using our service"
}
}
}
コンポーネントでの使用
import { useTranslations } from 'next-intl';
export default function HomePage() {
const t = useTranslations('home');
const tc = useTranslations('common');
return (
<main>
<h1>{t('hero.title')}</h1>
<p>{t('hero.subtitle', { count: 1500 })}</p>
<nav aria-label={tc('navigation.home')}>
<a href="/">{tc('navigation.home')}</a>
<a href="/about">{tc('navigation.about')}</a>
</nav>
</main>
);
}
翻訳の一括生成
Claude Codeに翻訳ファイルの生成を依頼できます。
> src/messages/ja.json を元に英語の翻訳ファイルを生成して。
> 技術用語はそのまま英語で、UIテキストは自然な英語にして。
翻訳漏れのチェック
> ja.jsonとen.jsonのキーを比較して、翻訳漏れがないかチェックして。
> 不足しているキーがあれば追加して。
// scripts/check-translations.ts
import ja from '../src/messages/ja.json';
import en from '../src/messages/en.json';
function getKeys(obj: object, prefix = ''): string[] {
return Object.entries(obj).flatMap(([key, value]) => {
const path = prefix ? `${prefix}.${key}` : key;
if (typeof value === 'object' && value !== null) {
return getKeys(value as object, path);
}
return [path];
});
}
const jaKeys = new Set(getKeys(ja));
const enKeys = new Set(getKeys(en));
const missingInEn = [...jaKeys].filter(k => !enKeys.has(k));
const missingInJa = [...enKeys].filter(k => !jaKeys.has(k));
if (missingInEn.length) {
console.log('Missing in en.json:', missingInEn);
}
if (missingInJa.length) {
console.log('Missing in ja.json:', missingInJa);
}
日付・数値のフォーマット
import { useFormatter } from 'next-intl';
function PriceDisplay({ amount, date }: { amount: number; date: Date }) {
const format = useFormatter();
return (
<div>
<p>{format.number(amount, { style: 'currency', currency: 'JPY' })}</p>
<time>{format.dateTime(date, { year: 'numeric', month: 'long', day: 'numeric' })}</time>
<p>{format.relativeTime(date)}</p>
</div>
);
}
// ja: ¥1,500 / 2026年3月24日 / 2週間前
// en: $1,500 / March 24, 2026 / 2 weeks ago
言語切り替えコンポーネント
'use client';
import { useRouter, usePathname } from 'next/navigation';
import { useLocale } from 'next-intl';
function LanguageSwitcher() {
const locale = useLocale();
const router = useRouter();
const pathname = usePathname();
const switchLocale = (newLocale: string) => {
const newPath = pathname.replace(`/${locale}`, `/${newLocale}`);
router.push(newPath);
};
return (
<div role="radiogroup" aria-label="言語選択">
<button
role="radio"
aria-checked={locale === 'ja'}
onClick={() => switchLocale('ja')}
className={locale === 'ja' ? 'font-bold' : ''}
>
日本語
</button>
<button
role="radio"
aria-checked={locale === 'en'}
onClick={() => switchLocale('en')}
className={locale === 'en' ? 'font-bold' : ''}
>
English
</button>
</div>
);
}
まとめ
Claude Codeを使えば、i18n基盤の構築から翻訳ファイルの生成、翻訳漏れのチェックまでを効率的に進められます。特に翻訳ファイルの一括生成と整合性チェックは、Claude Codeの強みが発揮される場面です。プロジェクトの多言語対応方針はCLAUDE.mdに記述しておくと一貫性を保てます。またプロンプトテクニックを使って翻訳の品質を高めることもできます。
Claude Codeの詳細はAnthropic公式ドキュメントをご覧ください。
#Claude Code
#i18n
#国際化
#多言語対応
#React
関連記事
Use Cases
Use Cases
Claude CodeでCORS設定完全ガイド:クロスオリジン通信の実践解説
Claude Codeを活用したCORS設定の完全ガイド。プリフライトリクエスト、認証付きリクエスト、トラブルシューティングまで実践的に解説します。
Use Cases
Use Cases
Claude Codeで通貨フォーマットを正しく実装する
Claude Codeを使って、多通貨対応・ロケール別フォーマット・為替レート変換など、通貨の表示と処理を正しく実装する方法を解説します。
Use Cases
Use Cases
Claude CodeでDiscord Botを開発する実践ガイド
Claude Codeを活用したDiscord Botの開発方法を解説。discord.js、スラッシュコマンド、ボタン操作、Embed、音声チャンネル連携まで実践的に紹介します。