雲端基礎設施
語系與在地化
在單一網站中支援多種語系,包含主要語系、無需額外點數的機器翻譯、語系感知傳遞與 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,upsertwithsourceHash,publish,delete,translate),localization.jobs.*; REST/sites/:id/locales,/sites/:id/translations - 託管網站
/settingslocale 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/feedwithresolvedLocale/availableLocales/localePaths(collection items:localeSlugs), any locale's slug resolves to the record;/redirectsrules carrylocale; Customer APIlocaleon deliverables, orders and unit open; SDKcreateKanorioMiddleware({ features: { locales } }),buildAlternates,requestLocaleOf,languageSwitcher, locale-scopedrevalidate; CLIdoctori18n rules - Elements
localeon<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-localellms.txt/rss.xml, one sitemap withxhtml:link, hreflang andx-default - Webhooks
cacheTagson 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
給網站擁有者
如何在後台使用這項產品,請參閱說明中心。
開啟說明中心