How to Efficiently Implement i18n: Claude Code 활용 가이드
efficiently implement i18n: Claude Code 활용. 실용적인 코드 예시와 단계별 가이드를 포함합니다.
多言語대응で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": "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: 'USD' })}</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="Language selection">
<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 워크플로우를 한 단계 업그레이드하세요
지금 바로 Claude Code에 복사해 쓸 수 있는 검증된 프롬프트 템플릿 50선.
이 글을 작성한 사람
Masa
Claude Code를 적극 활용하는 엔지니어. 10개 언어, 2,000페이지 이상의 테크 미디어 claudecode-lab.com을 운영 중.
관련 글
Claude Code로 리팩토링을 자동화하는 방법
Claude Code를 활용해 코드 리팩토링을 효율적으로 자동화하는 방법을 알아봅니다. 실전 프롬프트와 구체적인 리팩토링 패턴을 소개합니다.
Claude Code로 사이드 프로젝트 개발 속도를 극대화하는 방법 [예제 포함]
Claude Code를 활용해 개인 프로젝트 개발 속도를 획기적으로 높이는 방법을 알아봅니다. 실전 예제와 아이디어부터 배포까지의 워크플로를 포함합니다.
Complete CORS Configuration Guide: Claude Code 활용 가이드
complete cors configuration guide: Claude Code 활용. 실용적인 팁과 코드 예시를 포함합니다.