key 永远不会被切分, 每个 key 都按字面存储和查找。当你的 key 含有点号或本身就是自然文本时选择它:版本号、价格、文件名、圣经或法律引用。App Version 6.3.8 就保持其原样。
指南 · key 嵌套
扁平 key 还是嵌套 key
默认情况下,Sonenta 会按 . 将你的 key 切分到 CDN bundle 中的一个嵌套 JSON 树里, 这是经典的 i18next 形态。对于像 checkout.review.confirm 这样有组织的 key 很合适,但它会悄无声息地破坏那些文本中含有点号的 key。本指南介绍项目设置以及对应的 SDK 选项,以确保你的查找始终能解析成功。
带点号 key 的陷阱
key 不过是一个字符串。当该字符串包含一个字面点号时, 比如像 App Version 6.3.8 这样的版本号、一个价格、一个文件名、像 Jean 3.16 这样的圣经经文引用, 按 . 切分会把一个 key 变成一个意外的嵌套对象。翻译仍然被存储着,但 t("App Version 6.3.8") 再也找不到它了。
bundle.json 1// your source key, a literal label with dots in it2{ "App Version 6.3.8": "App Version 6.3.8" } 4// nested bundle (default), split on "." → broken tree5{ "App Version 6": { "3": { "8": "App Version 6.3.8" } } } 7// flat bundle, the key stays literal, lookups just work8{ "App Version 6.3.8": "App Version 6.3.8" } 项目设置
两个项目级设置控制着 CDN bundle 的形态。默认值复现当前的 i18next 行为,因此在你显式选择启用之前,已有项目不受影响。
| 设置 | 取值 | 默认值 |
|---|---|---|
| bundle_key_style | nested | flat | nested |
| bundle_key_separator | string | "." |
在项目上设置它们, 在你 dashboard 的项目设置中,或通过 projects API。所选的风格会被固化进每一个 release,且每个已发布的版本都会回报它,因此任何客户端都能自我配置。
versions/main 1# the version object reports the active key style2GET /v1/projects/<project_uuid>/versions/main 4{ "slug": "main", "key_style": "flat", "key_separator": "." } 选择扁平还是嵌套
key 会按分隔符切分到一个 JSON 树中, 经典的 i18next 布局。为像 checkout.review.confirm 这样刻意做了 namespace 划分的 key 选择它。这是默认值。
在 SDK 中保持一致
@sonenta/react-i18next(>= 0.11.0)接受一个 keySeparator 选项:false 表示字面 / 扁平查找,字符串表示嵌套,默认 "."。还有 nsSeparator(默认 ":")。SDK 是字面优先的, 它会在做任何切分之前先尝试精确的 bundle[key] 匹配,因此带点号的 key 即使在嵌套模式下也能解析成功。在 start() 时,它还会从已发布的版本中自动检测 key_style / key_separator(尽力而为)。
main.tsx 1// src/main.tsx, match the bundle in @sonenta/react-i18next >= 0.11.02import { SonentaProvider } from "@sonenta/react-i18next"; 4<SonentaProvider5 projectUuid="<project_uuid>"6 token={import.meta.env.VITE_SONENTA_TOKEN}7 keySeparator={false} // literal lookup, for dotted / natural-text keys8 nsSeparator=":" // default; set false to disable ns parsing too9>10 <App />11</SonentaProvider> 13// then t() treats the whole string as one key, no splitting14t("App Version 6.3.8"); // ✓ exact match 自动检测会读取版本元数据,并需要一个带 project:read 的 key。如果该读取被拒绝(403),SDK 会优雅地回退到它的默认值, 所以拿不准时,请显式设置 keySeparator 以匹配你的 bundle,而不是依赖检测。
建议
- key 含有点号?在项目上设置
bundle_key_style: flat,并在 SDK 中设置keySeparator={false}。两端都按字面处理, 没有意外。 - 干净地做了 namespace 划分的 key(
checkout.review.confirm)?保持嵌套默认值;无需改动。 - 正在迁移一个现有的 app?默认值会保留你当前的行为。仅在遇到带点号的 key 时才切换到 flat,然后重新发布并同时更新 SDK 选项。