# 语系与本地化

> 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/zh-CN/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**

网站设有一个主要语系，并可新增更多语系。每个文字字段皆保留其主要语系的数值；翻译内容则存储于旁边的资料表中，每一笔记录与语系各占一行。新增语系时，系统会在后台翻译整个网站，并于完成后发布。托管网站与您构建的任何前端，皆通过相同的 `locale` 参数读取相同的资料。

## 核心对象

- **语系集 (Locale set)。** 网站的语系包含一个主要语系、状态（`draft`、`translating`、`published`、`disabled`）、每个次要语系的网址前缀（`en`、`ja` 或拥有者自选的前缀）以及自动翻译开关。`GET /api/v1/site` 会在 `locales[]` 中列出这些信息。
- **翻译 (Translations)。** 每一笔记录与语系各占一行，包含草稿与已发布的字段资料、专属的网址别名（单一区段）以及翻译时来源记录的 `sourceHash`。哈希值用于检测过时的翻译，并防止外部工具覆盖较新的来源文字。
- **可翻译字段 (Translatable fields)。** 根据各内容类型架构衍生的注册表，定义哪些路径可进行翻译：标题、RTF 文字、区块文字、SEO 字段、产品描述、长篇详情、常见问题与购买备注、产品选项与变体描述、课程单元（包含文字课程与测验问题，但不包含答案）、全站处理时间与购买备注、表单及法律页面。集合字段需通过 `localized: true` 启用。价格、库存、订单、顾客与评论皆不进行翻译。
- **网址别名 (URL slugs)。** 页面、文章、分类、标签、作者、产品、产品分类与集合项目，每个语系皆可拥有自己的别名。首次机器翻译至某语系时，会从翻译后的标题产生别名（拉丁语系语言会产生 ASCII 别名；其他语言若主要别名为 ASCII 则保留该别名），之后不会自动变更。页面仅翻译其自身的区段，因此某语系中的页面路径是根据该语系中各层级的别名所构建。固定的永久链接区段（如 `/blog` 与 `/product`）不会被翻译。
- **翻译任务 (Translation jobs)。** 新增语系或重试失败批次时，会执行全站任务；后续对主要语系的编辑会以增量方式重新翻译。任务与单笔记录翻译不消耗 AI 点数；每日调用上限会将工作排入隔日，而非直接失败。

## 设置之间的关联

语系、货币、商业市场与时区是四个独立的设置。彼此互不依赖，因此网站可以使用英文撰写、以欧元销售，并采用东京时间运行。顾客的语系（`Contact.locale`）会在结账、登录与提交表单时记录，并决定其电子邮件、顾客账号与证书的语系。

## API 的运作方式

- **使用 Content Delivery API 读取。** 每次读取皆接受 `locale`（代码或网址前缀）。未翻译的字段会回退至主要文字，响应内容会在 `resolvedLocale` 中说明服务语系，并在 `availableLocales` 中列出已翻译的语系。通过别名读取时，接受任何语系的别名并返回该请求语系的 `slug`；页面与产品会新增 `localePaths`（在每个在线语系中的路径），集合项目则新增 `localeSlugs`。若网站不存在该语系，则返回 `400 UNSUPPORTED_LOCALE`。`/seo/*`、`/feed` 与搜索功能皆遵循相同的参数。请参阅 [读取内容](https://kanorio.com/zh-CN/developers/guides/read-content)。
- **使用 Management API 管理。** `localization.locales.*` 可新增、更新、重新排序、移除及设置主要语系；`localization.translations.*` 可列出、读取、写入（使用 `sourceHash` 进行 `upsert`，以及设置或清除语系的网址别名）、发布与删除翻译，并通过 `translate` 按需执行翻译；`localization.jobs.*` 可读取进度与重试。新增或移除语系会变更该语系的所有网址，并要求 `confirm: true`。语系代码为自然键：新增已存在的语系会返回 `ALREADY_ADDED`，移除不存在的语系会返回 `NOT_FOUND`，因此重试调用不会创建第二个语系，且无需幂等键。
- **监听 Webhooks。** `content.translation.published` 与 `deleted` 会针对每笔记录与语系触发；`localization.locale.published`、`unpublished` 与 `updated` 则在语系集变更时触发；`localization.job.completed` 与 `failed` 则针对全站任务触发。每个内容事件上的 `cacheTags` 带有 `@<locale>`，因此翻译上线时仅会刷新该语系。请参阅 [Webhooks](https://kanorio.com/zh-CN/developers/webhooks)。
- **在前端进行路由与标签。** `createKanorioMiddleware({ features: { locales: true } })` 会将主要语系的前缀重定向至根目录，提供 `/<prefix>/llms.txt` 与 `/<prefix>/rss.xml`，匹配不含前缀的共享重定向，并针对完整路径匹配语系重定向（`locale` 设置）。`requestLocaleOf`、`buildAlternates` 与 `languageSwitcher`（传入 `localePaths`）可让您取得语系、标准网址 (canonical)、hreflang 以及与托管网站规则相同的语言菜单。请参阅 [Next.js](https://kanorio.com/zh-CN/developers/guides/nextjs) 与 [SDK 参考](https://kanorio.com/zh-CN/developers/sdk)。
- **顾客端文字。** Customer API 与 `@kanorio/elements` 接受 `locale`；若未提供，则使用顾客记录的语系。课程与单元标题、订单项目名称与完成证书皆遵循此设置。请参阅 [课程与成员](https://kanorio.com/zh-CN/developers/guides/courses-and-members)。
- **自动化电子邮件。** 订单、付款、运送、退款、登录与表单确认邮件会以顾客记录的语系发送（若网站提供该语系），否则使用主要语系。若拥有者未自订电子邮件，则使用内置措辞（每个网站语言皆有对应版本）。自订电子邮件的翻译方式与其他内容相同：其翻译为 `message_template` 记录类型（自订模板的 ID），通过 `localization.translations.*` 针对各语系修正并于写入时生效。在语系拥有自订电子邮件的翻译前，该邮件会以主要语系发送。模板变量（如订单编号等三括号占位符）必须与来源完全一致；新增变量的翻译将被拒绝。
- **导出。** 网站导出内容包含主要语系内容旁边的 `localization/locales.json` 与 `localization/translations.json`。

## 应遵循的行为

- 主要语系于根目录提供；其他所有语系皆位于其前缀之下。主要语系本身的代码作为前缀时，会以 `301` 重定向至根目录。
- 仍在翻译中的语系对访客或 Delivery API 而言不存在。当任务完成时，该语系会一次性发布。
- 移除已上线的语系会将其前缀重定向至主要语系的页面。其翻译内容至少保留 30 天；重新新增该语系会重复使用这些翻译，并仅翻译缺失的部分。使用相同的前缀即可恢复旧网址。
- 以回退方式提供的页面（该语系尚未有翻译）会取得主要语系的标准网址 (canonical) 且不含 hreflang，因此搜索引擎不会索引重复内容。
- 具有草稿与发布生命周期的记录（页面、全局区块、网站设置、文章与集合项目）会将编辑过的翻译保留为草稿。发布记录会使每个语系的草稿上线；`localization.translations.publish` 可单独发布一个语系，并需要记录的发布权限（`site:publish`、`blog:publish` 或 `collections:publish`）。编辑翻译不会将主要语系标记为已变更。
- 使用其他语系别名的网址，或在语系已有专属别名时使用主要别名，皆会重定向至该语系的别名。变更已上线的别名会从该语系的旧网址新增 301；清除别名则会使该语系再次遵循主要别名。
- 网站仅有一个语系时可变更主要语系。在多语系网站上变更主要语系会重写所有网址，目前尚未开放此功能。
- 相同的规则适用于托管网站与无头 (headless) 前端；`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/zh-CN/help/multilingual-site
