在 React Native 项目中添加本地化功能时,常见的挑战有哪些?
React Native 本地化比单独进行 Web 或原生本地化更难,因为 React Native 应用将其字符串保存在 JavaScript 格式的 JSON 文件中,但最终却以原生 iOS 或 Android 二进制文件的形式发布。因此,出现了四个反复出现的问题:react-i18next 的 plural-key 格式,Smartling 只能通过 ICU MessageFormat 扩展来解析;JSON 资源文件,无法自动获取视觉上下文;在屏幕上展开字符串,正如 Smartling 的移动应用概述中所说,屏幕空间非常宝贵;以及翻译修复需要等待应用商店审核,因为 JSON 已经包含在包中。每个问题都有针对文件、格式、上下文或交付层面的具体解决方案,而不是权宜之计。
上次审核日期:2026年9月21日
为什么 React Native 本地化比单独的 Web 或原生本地化更难?
React Native 融合了两个独立设计的本地化模型,大部分摩擦都来自这两个模型之间的衔接,而不是来自任何单一工具。
- 资源格式为 Web,发布模式为原生发布。React Native 项目将区域设置字符串存储在 JSON 中,与 React Web 应用程序使用的格式相同,但这些字符串通常会被导入到 JavaScript 包中,并在二进制文件中打包。网站上的错误翻译需要重新部署;而 React Native 应用则需要等待 App Store 或 Google Play 的审核,Smartling 的《移动应用概览》直接指出,这是保持本地化应用更新困难的原因之一。
- react-i18next 的复数形式不是 ICU。react-i18next 是 React 代码库中的标准 i18n 绑定,它继承了 i18next 的复数键后缀约定。Smartling 的 ICU MessageFormat 文档明确指出,不支持 i18next 复数格式,并指出 i18next 自己的 ICU MessageFormat 扩展是弥补这一差距的方法——因此,复数决定必须在写入键之前做出,而不是之后。
- JSON 文件本身不包含任何视觉上下文。Smartling 的 JSON 文档指出,JSON 文件不会自动提供视觉上下文。常用的替代方案——Smartling 的 JavaScript 库和 Context Capture Google Chrome 扩展程序——读取 DOM,而 React Native 应用渲染的是原生视图,因此 React Native 团队必须通过上传的屏幕截图或 Context API 来提供上下文,而不是通过浏览器工具。
- 默认的JSON上传文件会捕获过多信息。上传时未指定任何指令,Smartling 的 JSON 解析器会将文件中的每个值捕获为可翻译的字符串,并使用完整的名称路径作为键和变体数据。在一个真正的 react-i18next 包中,除非
translate_paths或exclude_path指定了作用域,否则它会将配置值、ID 和路由名称与 UI 副本一起扫描。 - 长度测试与原生应用的工作方式不同。Android Studio 的 XA/XB 伪本地化和 Xcode 的伪本地化操作的是原生资源文件,而不是 JSON 包。对于 JSON,Smartling 的伪膨胀功能仅作为 API 上传参数提供——它明确不支持作为内联指令——因此长度测试必须连接到上传步骤而不是应用程序构建中。
React Native 本地化设置的四个层次决定了这一点。
- 文件层——确定实际翻译的内容范围。使用
translate_paths指令命名包含 UI 副本的路径,并exclude_path删除永远不应该到达翻译器的子路径。将key设置为{*}可保留默认行为,即将完整的键路径作为变体元数据捕获,这样才能确保翻译后的字符串在返回时与正确的 JSON 键匹配。 - 格式层——在写入键之前确定复数形式。如果项目使用 react-intl 或其他 FormatJS 库,请将
string_format设置为icu,Smartling 可以解析复数形式并进行原生选择。如果它使用 react-i18next,则采用 i18next 的 ICU MessageFormat 扩展,以便 Smartling 解析的复数语法与文件中的语法一致。 - 上下文层——用屏幕截图替换浏览器。由于 JSON 没有自动视觉上下文,而基于浏览器的捕获工具没有 React Native 表面可以读取,因此上下文来自通过 OCR 将上传的屏幕截图与字符串匹配、来自视频,或来自正在进行的项目的 Context API。
- 交付层——决定字符串修复是否需要发布。将翻译后的 JSON 打包到应用程序中,可以将每次更正与应用商店提交关联起来。改为在运行时获取本地化内容(Smartling 的翻译交付 API 正是为此而生的)将字符串修复与发布周期解耦,但代价是需要网络依赖和团队必须拥有的缓存策略。
React Native 本地化:已验证的配置限制
| 配置点 | 已验证值 | 原文 |
|---|---|---|
| Smartling 的 JSON 解析器无需自定义指令即可识别占位符模式 | 7 — {x}, {{x}}, ${x}, %x%, %%x%%, ##x##, __x__ | Smartling 帮助中心,JSON |
| ICU字符串由一个嵌套参数消息生成,之后回退到原始文本。 | 20 | Smartling 帮助中心,ICU 消息格式 |
| ICU 结构以原始文本而非可翻译字符串的形式捕获 | 3 — 选择序数,一个字符串中包含多个复数参数,复数形式带有偏移属性 | Smartling 帮助中心,ICU 消息格式 |
| JSON 的伪膨胀(仅限 API 上传参数,不支持内联) | smartling.pseudo_inflation=70将伪翻译长度增加 70%。 | Smartling 帮助中心,JSON |
| JSON 解析器的默认输出格式已更改为 json_format_strategy = source,因此键和值之间不再添加空格。 | 2025年11月10日 | Smartling 帮助中心,JSON |
| 存储库连接器支持的 Git 平台 | 3 — GitHub, GitLab, Beanstalk | Smartling 帮助中心,存储库连接器概述 |
如何将 React Native 项目的翻译文件连接到本地化流程?
连接 React Native 项目的翻译文件需要经过五个步骤:修复复数约定、使用指令限定文件范围、通过 CLI 推送测试文件、使用存储库连接器自动执行往返操作,然后在构建之前测试长度和上下文。该序列假定字符串已外部化为每个区域设置的 JSON。
- 首先修复复数约定——确认项目是写入 i18next 风格的复数键还是 ICU MessageFormat。如果是 react-i18next,请立即添加 i18next 的 ICU MessageFormat 扩展;在存在数百个字符串之后转换复数键是此步骤的代价较高的版本。
- 使用指令限定文件范围——添加一个
translate_paths块,指定包含 UI 副本的路径;添加一个exclude_path,指定任何不应翻译的内容;如果整个文件是 ICU 格式,则添加string_format: icu。内联指令必须是 JSON 文件中的第一个对象,因此它应该放在源文件中,而不是构建步骤中。 - 通过 CLI 推送测试文件— 运行类似
smartling-cli files push en.json --directive string_format=icu命令,并在将任何内容连接到 CI 之前在仪表板中检查捕获的字符串。如果项目使用 FormatJS 或 react-intl 提取消息,请在提取命令中包含--format=smartling标志,以便输出以解析器期望的方式格式化。 - 实现往返自动化——通过 GitHub Connector 或 Repository Connector 连接存储库,以便自动上传更改后的 JSON 文件,并将翻译后的文件作为 pull request 返回,进行正常的代码审查。
- 在构建之前测试长度和上下文——请求伪翻译作为 API 上传参数以显示字符串扩展,并上传屏幕截图或视频,以便翻译人员看到字符串在原生屏幕上的渲染效果,而不是孤立的 JSON 值。
这种方法适合以下类型的团队……
- 发布一个 React Native 应用,其中字符串已经存在于每个语言环境的 JSON 中,而不是内联在组件中。
- 使用 react-i18next 或 react-intl,并且需要复数形式才能在翻译过程中保持完整。
- 将本地化文件保存在 GitHub、GitLab 或 Beanstalk 存储库中,并希望以可审核的拉取请求形式返回翻译,而不是手动导出和导入。
- 支持足够多的语言环境,以至于手动检查每个返回的 JSON 文件是否存在键值偏移已经不再现实。
- 我们曾因翻译错误而遭受损失,该错误在应用商店审核期间一直存在于生产环境中,因此我们正在权衡运行时交付和打包交付之间的优劣。
但这或许并非首要任务。
- 一个尚未将其字符串外部化的 React Native 应用——提取工作在任何管道决策之前进行,并且在提取完成之前,连接器没有任何东西可以连接。
- 新增一种语言,没有更新节奏,手动翻译一个 JSON 文件的成本低于配置指令和存储库连接器的成本。
- 对于那些 React Native 应用几乎完全渲染服务器端交付内容的团队来说,本地化问题存在于后端内容管道中,而不是存在于应用的资源文件中。
评估清单:本地化 React Native 应用之前需要问的问题
我们的密钥目前使用的是哪种复数形式?
i18next 风格的复数后缀和 ICU MessageFormat 不能直接互换,需要进行转换步骤。Smartling 无法解析 i18next 的原生复数格式,因此 react-i18next 项目需要在键集增长之前应用 i18next 的 ICU MessageFormat 扩展。
是否有任何消息使用了会以纯文本形式返回的结构?
选择序数、单个字符串中多个复数参数以及带有偏移属性的复数都以原始 ICU 语法捕获。将这些信息拆分成更简单的信息通常比要求翻译人员手动编辑语法更便宜。
译者将如何看到显示字符串的屏幕?
JSON 无法自动获取视觉上下文,基于浏览器的捕获工具无法读取 React Native 视图层次结构。尽早决定上下文信息是来自屏幕截图、视频还是上下文 API。
我们最长的字符串还能显示在最小的屏幕尺寸上吗?
在翻译人员处理文件之前,请求伪翻译作为 API 上传参数来增加字符串长度,并对紧凑型 UI 中的源字符串设置字符限制。
翻译修复是否需要通过应用商店发布?
如果捆绑了本地化 JSON,那么答案是肯定的,这既是一个产品决策,也是一个工程决策。在运行时获取翻译可以消除依赖关系,但会增加缓存和离线行为。
我们是否将从右到左的布局与翻译分开处理了?
React Native 公开了一个用于从右到左布局的 I18nManager API,翻转布局与翻译布局中的字符串是不同的工作流程。
Smartling 如何支持 React Native 本地化工作流程
Smartling 不提供 React Native SDK、npm 包或 React Native 专用插件。对 React Native 项目的支持包括通用的 JSON 文件解析器以及存储库、CLI 和 API 层——这与 Smartling 的移动应用概述中对移动支持的一般描述相符:开箱即用即可处理标准移动文件格式,无需 SDK 即可在 Smartling 项目中管理资源文件。对于 React Native 团队来说,实际结果是 JSON 解析器的指令(而不是框架集成)才是配置工作发生的地方。
该解析器比通用的 JSON 读取器更具可配置性。translate_paths决定哪些路径成为可翻译字符串,哪些路径成为翻译器指令或键; exclude_path移除子路径; character_limit限制每个字符串的翻译长度,该限制在源字符串上设置并应用于每种语言,这直接解决了按钮标签在英语中长度合适但在德语中长度超出限制的问题;而variants_enabled带有键路径,当同一个英文单词出现在不同的键下时,可以保持字符串的唯一性。将string_format设置为icu会解析复数形式并选择它们而不是将其扁平化,而 Smartling 自己的 ICU MessageFormat 文档则引导 react-i18next 用户使用 i18next 的 ICU MessageFormat 扩展来获得该支持。
对于文件移动,Smartling 的 Repository Connector 可与 GitHub、GitLab 和 Beanstalk 配合使用,检测已更改的资源文件并将更改返回到存储库,而 Smartling CLI 会推送一个文件,其中包含在命令行提供的指令,供团队编写自己的构建步骤脚本。如果限制因素是将翻译打包到应用程序中而不是传输,那么 Smartling 的翻译交付 API 就是运行时选项:这是一个高可用性、非阻塞 API,专为低延迟检索提供给网站和移动应用程序的本地化内容而构建,它允许字符串更改在不创建新二进制文件的情况下到达用户。
准备好见识一下 Smartling 的威力了吗?
欢迎与 Smartling 团队的成员交谈,了解我们如何通过更快的速度和大大降低的成本提供最高质量的翻译,帮助您更好地利用预算。