vtex-io-messages-and-i18n について
VTEX IO アプリをローカライズする開発者向けのスキルです。メッセージファイルやキーの整理、コード内での利用方法を扱い、翻訳文と設定データを区別します。
主な機能
- 01メッセージファイルで翻訳文を管理
- 02context.json でメッセージキーを宣言
- 03画面や領域ごとにキーを整理
- 04React と Admin でローカライズ済みメッセージを利用
- 05翻訳文とアプリ設定を分離
活用シーン
- 01ストアフロントや Admin の画面に翻訳を追加
- 02JSX 内のハードコード文字列を置換
- 03メッセージキーとファイルの整合性を確認
- 04バックエンドでテキストを翻訳する場面を判断
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ vtex/ skills --skill vtex-io-messages-and-i18nインストール後、Claude Code で/vtex-io-messages-and-i18nを入力して読み込まれたか確認します。
詳細
メッセージと国際化
このスキルを使用する場面
VTEX IO アプリで、ハードコードされた文字列ではなく翻訳済みの文言が必要な場合に、このスキルを使用します。
- ストアフロントまたは Admin アプリにローカライズされた UI テキストを追加する場合
/messages/*.json翻訳ファイルを作成または更新する場合context.jsonでメッセージキーを定義する場合- ユーザー向けの文言を現在ハードコードしている React、Admin、またはバックエンドのコードをレビューする場合
- アプリ固有の翻訳を
vtex.messagesと統合する場合
次の目的には、このスキルを使用しないでください。
- 一般的な UI レイアウトやコンポーネントの構成
- 認可、ポリシー、または認証トークン
- サービスのランタイムサイズの設定
- HTTP、GraphQL、イベント駆動型 API の選択
判断ルール
- ユーザー向けの文言には、ソースコードにラベル、ボタンテキスト、UI メッセージをハードコードするのではなく、
messagesビルダーと翻訳ファイルを使用します。 titleやbuttonのような汎用キーではなく、安定性があり、明示的で、アプリのドメインにスコープされた翻訳キーを維持します。形式はさまざまですが、キーはアプリ固有で、説明的かつ、どのアプリに属するかが明確である必要があります。- ストアフロントのメッセージには
store/...、Admin または Site Editor のメッセージにはadmin/...のように、UI の表示箇所またはドメインに応じてメッセージ ID にプレフィックスを付けます。これにより、キーを整理し、コンテキスト間での重複を防げます。 - VTEX IO がアプリの翻訳対象を検出して管理できるよう、
/messages/context.jsonでメッセージキーを定義します。messageId -> descriptionのフラットなマップを維持し、アプリで実際に使用するキーを含めます。 - 翻訳済みメッセージのペイロードは小さく保ち、アプリに関連する内容に限定します。messages システムを汎用コンテンツストアにしないでください。
- React または Admin の UI では、JSX に文言を直接記述するより、メッセージ ID とローカライズ用ヘルパーを優先します。
- バックエンドまたは GraphQL のフローでは、アプリの境界でローカライズ済みテキストが本当に必要な場合に限り翻訳します。それ以外の場合は、安定した機械処理向けのデータを返し、呼び出し元で表示内容をローカライズします。
- 通常のアプリローカルのメッセージファイルでは対応できない翻訳動作やメッセージ解決のカスタマイズがアプリに本当に必要な場合に限り、
vtex.messagesのアプリレベルのオーバーライドを使用します。
厳守すべき制約
制約:ユーザー向け文字列はメッセージインフラストラクチャから取得する必要があります
ユーザー向け文字列は、コンポーネント、ハンドラー、またはリゾルバーにハードコードするのではなく、メッセージインフラストラクチャから取得しなければなりません。
重要な理由
文言をハードコードすると、ローカライズができなくなり、メッセージのレビューが難しくなり、ストアフロント、Admin、バックエンドの各フローで動作に一貫性がなくなります。
検出方法
ローカライズ対象のアプリで、ラベル、ボタン、見出し、アラート、その他のユーザー向けテキストが JSX やバックエンドのレスポンス整形に直接埋め込まれている場合は、作業を中断し、その文言をメッセージファイルに移してください。
適切な例
<FormattedMessage id="admin/my-app.save" />
不適切な例
<button>Save</button>
制約:メッセージキーは明示的に宣言し、整理する必要があります
メッセージキーはアプリにスコープされ、コード内で場当たり的に作成するのではなく、アプリのメッセージ設定に記載しなければなりません。
重要な理由
構造化されていないキーは保守が難しくなり、アプリ領域間で重複し、メッセージの管理元が不明確になります。
検出方法
対応する翻訳ファイルや context.json のエントリーがないメッセージ ID をコードに新たに追加している場合は、作業を中断し、メッセージの定義を明示的に追加してください。
適切な例
{
"admin/my-app.save": "Save"
}
不適切な例
{
"save": "Save"
}
制約:messages システムを汎用コンテンツストアや設定ストアとして使用してはなりません
翻訳ファイルにはローカライズされた文言のみを含め、運用設定、シークレット、大規模なコンテンツペイロードを含めてはなりません。
重要な理由
messages インフラストラクチャは翻訳済み文字列を扱うために設計されています。それ以外のデータに使用すると、保守に混乱を招き、ローカライズに関する関心事と設定やコンテンツの保存が混在します。
検出方法
メッセージファイルに API URL、認証情報、ビジネスルール、または長い構造化コンテンツの塊が含まれている場合は、作業を中断し、そのデータをアプリ設定、設定用アプリ、またはコンテンツ専用の仕組みに移してください。
適切な例
{
"store/my-app.emptyState.title": "No records found"
}
不適切な例
{
"apiBaseUrl": "https://partner.example.com",
"featureFlags": {
"betaMode": true
}
}
推奨されるパターン
推奨されるファイル構成:
.
├── messages/
│ ├── context.json
│ ├── en.json
│ └── pt.json
└── react/
└── components/
└── SaveButton.tsx
最小限のメッセージ設定:
// messages/context.json
{
"admin/my-app.save": "Label for the save action in the admin settings page"
}
// messages/en.json
{
"admin/my-app.save": "Save",
"store/my-app.emptyState.title": "No records found"
}
// messages/pt.json
{
"admin/my-app.save": "Salvar"
}
import { FormattedMessage } from 'react-intl'
export function SaveButton() {
return <FormattedMessage id="admin/my-app.save" />
}
バックエンドまたは GraphQL の翻訳パターン:
scalar IOMessage
type ProductLabel {
id: ID
label: IOMessage
}
type Query {
productLabel(id: ID!): ProductLabel
}
export const resolvers = {
Query: {
productLabel: async (_: unknown, { id }: { id: string }) => {
return {
id,
label: {
content: 'store/my-app.product-label',
description: 'Label for product badge',
from: 'en-US',
},
}
},
},
}
アプリの主な対象者が別のロケールを使用している場合でも、完全な en.json をデフォルトのフォールバックとして維持してください。これにより、メッセージシステムでの解決と自動翻訳の動作に、安定した基盤を確保できます。
コードでは翻訳済みの ID を使用し、翻訳ファイルを明示的に管理してください。また、リテラルをアプリ内に散在させるのではなく、ユーザーに表示するテキストをメッセージシステムに集約してください。
よくある問題
- JSX、リゾルバー、ハンドラーのレスポンスに、ユーザーに表示する文字列をハードコードする。
context.jsonやメッセージファイルを更新せずに、コード内に新しいメッセージ ID を追加する。title、save、buttonのような汎用的で衝突しやすいキーを使用する。- 設定値やローカライズ対象ではないビジネスペイロードをメッセージファイルに保存する。
- アプリ内でのメッセージ管理ではなく、
vtex.messagesのオーバーライドを標準的な方法として扱う。
レビューチェックリスト
- ユーザーに表示する文字列は、コードにハードコードせず、メッセージインフラストラクチャから取得していますか?
- メッセージキーは明示的で、アプリのスコープに限定され、一貫して宣言されていますか?
-
context.jsonは、アプリで使用する翻訳対象を反映していますか? - メッセージファイルには、設定や運用データではなく、ローカライズ対象のテキストだけが含まれていますか?
-
vtex.messagesのカスタマイズは、このアプリに本当に必要ですか?
関連スキル
vtex-io-storefront-react- 主な課題が、ストアフロントのコンポーネント構成や購入者向け UI の動作である場合に使用しますvtex-io-admin-react- 主な課題が、Admin UI の構成や運用時の操作パターンである場合に使用しますvtex-io-graphql-api- 主な課題が翻訳インフラストラクチャではなく、GraphQL スキーマやリゾルバーの設計である場合に使用します
参考資料
- メッセージ - VTEX の messages アプリとランタイムでの翻訳動作
- Messages アプリの上書き - アプリ固有の
vtex.messagesオーバーライドの仕組み