# ロケールとローカリゼーション

> Several locales in one site, with a primary locale, machine translation that costs no credits, locale-aware delivery and SEO, and the same contract for hosted and headless front ends.

> Markdown version of https://kanorio.com/ja/developers/products/localization. Append `.md` to any developer docs URL for this format. Index: https://kanorio.com/llms.txt · MCP: https://app.kanorio.com/api/mcp
>
> Translated from the English original: https://kanorio.com/en/developers/products/localization.md

Status: **Available**

サイトには1つのプライマリロケールがあり、さらにロケールを追加できます。すべてのテキストフィールドは、プライマリロケールの値をそのまま保持します。翻訳は、レコードとロケールごとに1行ずつ、隣接するテーブルに保存されます。ロケールを追加すると、サイト全体がバックグラウンドで翻訳され、完了後に公開されます。ホストされたサイトおよび構築したフロントエンドは、同じ `locale` パラメータを通じて同じデータを読み取ります。

## コアオブジェクト

- **ロケールセット** サイトのロケール。プライマリロケール、ステータス（`draft`、`translating`、`published`、`disabled`）、各セカンダリロケールのURLプレフィックス（`en`、`ja`、または所有者が選択したプレフィックス）、および自動翻訳スイッチが含まれます。`GET /api/v1/site` で `locales[]` として一覧表示されます。
- **翻訳** レコードとロケールごとに1行。ドラフトおよび公開済みのフィールドデータ、独自のURLスラッグ（1セグメント）、および翻訳時点のソースレコードの `sourceHash` を保持します。このハッシュにより、古い翻訳の検出や、外部ツールによる新しいソーステキストの上書き防止が可能になります。
- **翻訳可能なフィールド** コンテンツタイプのスキーマから派生したレジストリで、翻訳可能なパス（タイトル、リッチテキスト、セクションテキスト、SEOフィールド、製品説明、詳細、FAQ、購入メモ、製品オプション、バリエーション説明、コースユニット（テキストレッスンやクイズ問題を含む。回答キーは除く）、ストア全体の処理時間や購入メモ、フォーム、法務ページなど）が定義されています。コレクションフィールドは `localized: true` で有効化します。価格、在庫、注文、顧客、レビューは翻訳されません。
- **URLスラッグ** ページ、投稿、カテゴリ、タグ、著者、製品、製品カテゴリ、コレクションアイテムごとに、ロケール固有のスラッグを設定できます。ロケールへの最初の機械翻訳時に、翻訳されたタイトルから生成されます（ラテン文字言語はASCIIスラッグ、その他のスクリプトはASCIIの場合はプライマリスラッグを保持）。その後、自動的に変更されることはありません。ページは自身のセグメントのみを翻訳するため、ロケール内でのパスは各階層のスラッグから構築されます。`/blog` や `/product` などの固定パーマリンクセグメントは翻訳されません。
- **翻訳ジョブ** ロケールの追加時や失敗したバッチの再試行時にサイト全体のジョブが実行されます。プライマリロケールへのその後の編集は、段階的に再翻訳されます。ジョブや単一レコードの翻訳にはAIクレジットは消費されません。1日の呼び出し上限に達した場合は、失敗するのではなく翌日にキューイングされます。

## 設定の関連性

ロケール、通貨、ビジネス市場、タイムゾーンは4つの独立した設定です。これらは相互に依存しないため、英語で記述し、ユーロで販売し、東京時間で運用するサイトを作成できます。顧客のロケール（`Contact.locale`）は、チェックアウト、ログイン、フォーム送信時に記録され、メール、顧客アカウント、証明書のロケールを決定します。

## APIの適合性

- **Content Delivery APIによる読み取り** すべての読み取りで `locale`（コードまたはURLプレフィックス）を受け入れます。翻訳されていないフィールドはプライマリテキストにフォールバックし、レスポンスには `resolvedLocale`（提供されたロケール）と `availableLocales`（翻訳が存在するロケール）が含まれます。スラッグによる読み取りは任意のロケールのスラッグを受け入れ、要求されたロケールの `slug` を返します。ページや製品には `localePaths`（すべての公開ロケールでのパス）が追加され、コレクションアイテムには `localeSlugs` が追加されます。サイトに存在しないロケールを要求すると `400 UNSUPPORTED_LOCALE` が返されます。`/seo/*`、`/feed`、および検索も同じパラメータに従います。[コンテンツの読み取り](https://kanorio.com/ja/developers/guides/read-content)を参照してください。
- **Management APIによる管理** `localization.locales.*` でロケールの追加、更新、並べ替え、削除、プライマリロケールの設定を行います。`localization.translations.*` で翻訳の一覧表示、読み取り、書き込み（`sourceHash` を指定した `upsert`、およびロケールのURLスラッグを設定・クリアするための `slug`）、公開、削除、および `translate` によるオンデマンド実行を行います。`localization.jobs.*` で進捗の読み取りと再試行を行います。ロケールの追加や削除はすべてのURLを変更するため、`confirm: true` が必要です。ロケールコードは自然キーです。セット内に存在するロケールの追加は `ALREADY_ADDED` を返し、存在しないロケールの削除は `NOT_FOUND` を返すため、再試行によって重複して作成されることはなく、べき等キーは不要です。
- **Webhookの受信** `content.translation.published` および `deleted` はレコードとロケールごとに発生します。`localization.locale.published`、`unpublished`、`updated` はロケールセットの変更時に発生します。`localization.job.completed` および `failed` はサイト全体のジョブに対して発生します。すべてのコンテンツイベントの `cacheTags` には `@<locale>` が含まれるため、翻訳が公開されると、そのロケールのみが更新されます。[Webhook](https://kanorio.com/ja/developers/webhooks)を参照してください。
- **フロントエンドでのルーティングとタグ付け** `createKanorioMiddleware({ features: { locales: true } })` は、プライマリロケールのプレフィックスをルートにリダイレクトし、`/<prefix>/llms.txt` および `/<prefix>/rss.xml` を提供し、プレフィックスなしの共有リダイレクトや、フルパスに対するロケールリダイレクト（`locale` セット）を照合します。`requestLocaleOf`、`buildAlternates`、`languageSwitcher`（`localePaths` を渡す）を使用すると、ホストされたサイトと同じルールでロケール、正規URL、hreflang、言語メニューを取得できます。[Next.js](https://kanorio.com/ja/developers/guides/nextjs) および [SDKリファレンス](https://kanorio.com/ja/developers/sdk)を参照してください。
- **顧客向けテキスト** Customer API および `@kanorio/elements` は `locale` を受け入れます。指定がない場合は、顧客の記録されたロケールを使用します。コースやユニットのタイトル、注文明細名、修了証明書はこれに従います。[コースとメンバー](https://kanorio.com/ja/developers/guides/courses-and-members)を参照してください。
- **自動送信メール** 注文、支払い、配送、返金、サインイン、フォーム確認メールは、サイトが提供している場合は顧客の記録されたロケールで、それ以外の場合はプライマリロケールで送信されます。所有者がカスタマイズしていないメールは、すべてのサイト言語で用意されている組み込みの文言を使用します。カスタマイズされたメールは他のコンテンツと同様に翻訳されます。その翻訳は `message_template` レコードタイプ（カスタマイズされたテンプレートのID）であり、`localization.translations.*` でロケールごとに修正され、書き込み時に反映されます。ロケールにカスタマイズされたメールの翻訳が存在するまでは、プライマリロケールで送信されます。テンプレート変数（注文番号などの三重中括弧のプレースホルダー）はソースと完全に一致させる必要があります。変数を追加する翻訳は拒否されます。
- **エクスポート** サイトのエクスポートには、プライマリロケールのコンテンツに加えて `localization/locales.json` および `localization/translations.json` が含まれます。

## 信頼すべき動作

- プライマリロケールはルートで提供され、他のすべてのロケールはそのプレフィックスの下で提供されます。プライマリロケール自身のコードをプレフィックスとして使用すると、`301` でルートにリダイレクトされます。
- 翻訳中のロケールは、訪問者やDelivery APIに対しては存在しないものとして扱われます。ジョブが完了すると、ロケールは一度に公開されます。
- 公開されていたロケールを削除すると、そのプレフィックスはプライマリロケールのページにリダイレクトされます。翻訳は少なくとも30日間保持され、ロケールを再度追加すると再利用され、不足分のみが翻訳されます。古いURLを復元するには同じプレフィックスを指定してください。
- フォールバックで提供されるページ（ロケールに翻訳がまだない場合）は、プライマリロケールの正規URLを取得し、hreflangは設定されないため、検索エンジンが重複テキストをインデックスすることはありません。
- ドラフトと公開のライフサイクルを持つレコード（ページ、グローバルセクション、サイト設定、投稿、コレクションアイテム）は、編集された翻訳をドラフトとして保持します。レコードを公開すると、すべてのロケールのドラフトが公開されます。`localization.translations.publish` は特定のロケールのみを公開し、レコードの公開権限（`site:publish`、`blog:publish`、または `collections:publish`）が必要です。翻訳を編集しても、プライマリロケールが変更済みとしてマークされることはありません。
- 他のロケールのスラッグを使用しているURL、またはロケール固有のスラッグがある場合のプライマリスラッグは、そのロケールのスラッグにリダイレクトされます。公開中のスラッグを変更すると、そのロケールで古いURLから `301` リダイレクトが追加されます。クリアすると、ロケールは再びプライマリスラッグに従うようになります。
- サイトにロケールが1つしかない場合は、プライマリロケールを変更できます。多言語サイトでの変更はURLをすべて書き換えるため、現在は提供されていません。
- 同じルールがホストされたサイトとヘッドレスフロントエンドの両方に適用されます。`npx @kanorio/cli doctor` は、フロントエンドが各ロケールをプレフィックスの下で翻訳済みタイトルとともに提供しているか、すべての公開ロケールに対してhreflangを一覧表示しているか、ロケールごとの `llms.txt` を提供しているかを確認します。

## What the APIs expose

| Capability | Status | API | Elements | Hosted site | Webhooks |
| --- | --- | --- | --- | --- | --- |
| Locale set & translations (add a locale, full-site machine translation, review) | Available | Management API `localization.locales.*` (`list`, `add`, `update`, `reorder`, `remove`, `set_primary`), `localization.translations.*` (`list`, `get`, `upsert` with `sourceHash`, `publish`, `delete`, `translate`), `localization.jobs.*`; REST `/sites/:id/locales`, `/sites/:id/translations` | — | `/settings` locale list (status, progress, URL prefix, auto-translate) and the editor's locale switcher for corrections | `content.translation.published` / `deleted`, `localization.locale.published` / `unpublished` / `updated`, `localization.job.completed` / `failed` |
| Locale-aware delivery, SEO files and customer-facing text | Available | Delivery `?locale=` (code or URL prefix) on `/site`, `/pages`, `/globals`, `/collections`, `/catalog`, `/forms`, `/search`, `/seo/*` and `/feed` with `resolvedLocale` / `availableLocales` / `localePaths` (collection items: `localeSlugs`), any locale's slug resolves to the record; `/redirects` rules carry `locale`; Customer API `locale` on deliverables, orders and unit open; SDK `createKanorioMiddleware({ features: { locales } })`, `buildAlternates`, `requestLocaleOf`, `languageSwitcher`, locale-scoped `revalidate`; CLI `doctor` i18n rules | `locale` on `<KanorioProvider>` (forms, login, curriculum and unit load the visitor's locale) | Primary locale at the root, other locales under their prefix (`/en/…`), header language menu, per-locale `llms.txt` / `rss.xml`, one sitemap with `xhtml:link`, hreflang and `x-default` | `cacheTags` on every content event carry `@<locale>` so a translation going live refreshes only that locale |

## API reference

- Management API: [Localization](https://kanorio.com/en/developers/management-api/localization) (16 operations)

## Webhook events

- `content.translation.published`: Fired when one record's translation in one locale goes live on its own (editor correction, Management API write, incremental or on-demand machine translation). cacheTags carry only that locale's tags. Not fired per record during a full-site translation job; see localization.job.completed.
- `content.translation.deleted`: Fired when a live translation of one record in one locale is deleted; visitors see the primary-locale text until it is translated again.
- `localization.locale.published`: Fired when a locale goes live for visitors and the Content Delivery API (a full-site translation job finished, or the owner published it). cacheTags is site:<id>: rebuild the language switcher and hreflang on every page.
- `localization.locale.unpublished`: Fired when a live locale is taken offline or removed (removed: true); its URL prefix now 301-redirects to the primary locale.
- `localization.locale.updated`: Fired when a live locale's URL prefix (change: path_prefix, previous holds the old prefix), its position in the language switcher (order) or the site's primary locale (primary) changes.
- `localization.job.completed`: Fired when a full-site translation job finishes. cacheTags is locale:<code>: every response of that locale may have changed. A locale going live for the first time also fires localization.locale.published.
- `localization.job.failed`: Fired when a full-site translation job fails (the model provider stayed unavailable or retries ran out; the daily limit only pauses a job). Retry it with localization.jobs.retry.

Payloads: https://kanorio.com/en/developers/webhooks/events

## Recent changes

- 2026-11-04: Localization: automated emails follow the customer's language
- 2026-11-04: Localization: publishing one locale needs the record's publish permission
- 2026-11-04: Localization: more translatable fields (product details, variants, lessons, quizzes, store notes)
- 2026-11-04: Localization: each locale can have its own URL slug
- 2026-11-03: Localization is generally available; site export includes locales and translations

Full changelog: https://kanorio.com/en/developers/changelog

## For site owners

Dashboard help: https://kanorio.com/ja/help/multilingual-site
