Kanorio

云端基础设施

语系与本地化

在单一网站中支持多种语系,包含主要语系、无需额外点数的机器翻译、语系感知传递与 SEO,并为托管与无头前端提供相同的合约。

可用

网站设有一个主要语系,并可新增更多语系。每个文字字段皆保留其主要语系的数值;翻译内容则存储于旁边的资料表中,每一笔记录与语系各占一行。新增语系时,系统会在后台翻译整个网站,并于完成后发布。托管网站与您构建的任何前端,皆通过相同的 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 与搜索功能皆遵循相同的参数。请参阅 读取内容。
  • 使用 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。
  • 在前端进行路由与标签。 createKanorioMiddleware({ features: { locales: true } }) 会将主要语系的前缀重定向至根目录,提供 /<prefix>/llms.txt 与 /<prefix>/rss.xml,匹配不含前缀的共享重定向,并针对完整路径匹配语系重定向(locale 设置)。requestLocaleOf、buildAlternates 与 languageSwitcher(传入 localePaths)可让您取得语系、标准网址 (canonical)、hreflang 以及与托管网站规则相同的语言菜单。请参阅 Next.js 与 SDK 参考。
  • 顾客端文字。 Customer API 与 @kanorio/elements 接受 locale;若未提供,则使用顾客记录的语系。课程与单元标题、订单项目名称与完成证书皆遵循此设置。请参阅 课程与成员。
  • 自动化电子邮件。 订单、付款、运送、退款、登录与表单确认邮件会以顾客记录的语系发送(若网站提供该语系),否则使用主要语系。若拥有者未自订电子邮件,则使用内置措辞(每个网站语言皆有对应版本)。自订电子邮件的翻译方式与其他内容相同:其翻译为 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。

API 开放的范围

  • Locale set & translations (add a locale, full-site machine translation, review)可用
    API
    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
    Webhooks
    content.translation.published / deleted, localization.locale.published / unpublished / updated, localization.job.completed / failed
  • Locale-aware delivery, SEO files and customer-facing text可用
    API
    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
    Elements
    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
    Webhooks
    cacheTags on every content event carry @<locale> so a translation going live refreshes only that locale

API 参考

Webhook 事件

  • 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.

近期变更

  • 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
查看完整更新日志

给网站所有者

如何在后台使用这项产品,请参阅帮助中心。

打开帮助中心