zoonk-translations について
zoonk-translationsは、プロジェクトのnext-intl国際化ルールに沿って開発するためのスキルです。翻訳呼び出しやメッセージファイル、複数形、リッチテキストの扱いを案内します。
主な機能
- 01next-intlのサーバー・クライアント利用パターン
- 02静的な翻訳キーと文字列補間
- 03メタデータとサーバーアクションのロケール規則
- 04JSONメッセージファイルのワークフロー
- 05名前空間、複数形、リッチテキスト
活用シーン
- 01ページやUIのローカライズ文字列の追加
- 02翻訳済みメタデータやサーバーアクションの処理
- 03複数形やリッチテキストメッセージの実装
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ zoonk/ zoonk --skill zoonk-translationsインストール後、Claude Code で/zoonk-translationsを入力して読み込まれたか確認します。
詳細
国際化(i18n)ワークフロー
概要
このプロジェクトでは、国際化に next-intl を使用します。翻訳は JSON メッセージファイルに保存されます。
主な関数
- サーバーコンポーネント:
getTranslationsを使用します(ロケールは不要です) - クライアントコンポーネント:
useTranslationsを使用します - メタデータ/サーバーアクション:ロケールパラメーターを指定して
getTranslationsを使用します
重要なルール
1. 翻訳キーに動的な値を使用しない
重要:t 関数は、キーとして動的な値をサポートしていません。
// BAD: Dynamic key - will NOT work
const category = getCategory();
t(category); // Error!
t(MYLABELS[category]);
// GOOD: String literals only
t("Arts courses");
t("Business courses");
t("Technology courses");
2. 文字列補間はサポートされています
翻訳内の動的な値には、文字列補間を使用できます。
// GOOD: Interpolation with static key
t("Explore all {category} courses", { category: "arts" });
t("Welcome, {name}!", { name: user.name });
t("{count} items remaining", { count: 5 });
3. t 関数を別の場所に渡さない
t 関数を他の関数やコンポーネントに渡すことはできません。
// BAD: Passing t function
function myFunction(t, label) {
return t(label);
}
myFunction(t, "Some label");
// GOOD: Call t directly
function myFunction(translatedLabel: string) {
return translatedLabel;
}
myFunction(t("Some label"));
4. ロケールパラメーターのルール
// Server Component - no locale needed
const t = await getTranslations();
t("Hello");
// generateMetadata - needs locale
export async function generateMetadata({ params }) {
const { locale } = await params;
const t = await getTranslations({ locale });
return { title: t("Page Title") };
}
翻訳を追加するワークフロー
-
コードに翻訳呼び出しを追加する:
const t = await getTranslations(); return <h1>{t("New page title")}</h1>; -
メッセージファイルにキーを追加する:
ロケールディレクトリ(例:
messages/en.json、messages/es.json)にある JSON メッセージファイルを探し、新しいキーを追加します。{ "New page title": "New page title" } -
各ロケール向けに翻訳する:
// messages/es.json { "New page title": "Nuevo título de página" }
よく使われるパターン
条件付きテキスト
// Use separate translation keys
const status = isActive ? t("Active") : t("Inactive");
複数形化
// Use ICU message format
t("items", { count: 5 }); // "5 items"
メッセージファイル内:
{
"items": "{count, plural, =0 {No items} =1 {1 item} other {# items}}"
}
リッチテキスト(コンポーネントを使用)
t.rich("Read our {link}", {
link: (chunks) => <Link href="/terms">{chunks}</Link>,
});
メッセージファイル内:
{
"Read our {link}": "Read our <link>terms of service</link>"
}
ファイル構成
messages/
en.json # English translations
es.json # Spanish translations
pt.json # Portuguese translations
名前空間
規模の大きなアプリでは、翻訳を名前空間ごとに整理します。
// Server Component
const t = await getTranslations("Dashboard");
t("welcome"); // Looks up "Dashboard.welcome"
// Client Component
const t = useTranslations("Dashboard");
t("welcome");
{
"Dashboard": {
"welcome": "Welcome to your dashboard"
}
}
コメント
Markdown 対応