@deriv-com/translations
这是一个本地化库,使用 i18next, (中文(简体) ), react-i18next,以及用于翻译的自定义OTA SDK.
在本文件中
概览
所需资源
所存储的翻译目录必须具有以下结构:
{{ BASE_URL }}/translations/{lang}.json
base url 是 cdnUrl 传递到 initializeI18n 函数,而lang是语言代码。 参见 实例
开始
要开始,首先需要做的是:
- Crowdin 工程, 用于管理您的工程的翻译 .
- 一个Cloudflare R2账户来存储翻译.
- 在 R2 账户中创建新桶 .
- 在 R2 账户中创建新访问密钥 .
- 在您的仓库中添加以下秘密 :
CROWDIN_PROJECT_ID: 打开您的群集项目并导航到Tools选项卡中,您可以获取项目ID, 存储在您的 github 机密中 .CROWDIN_PERSONAL_TOKEN: 可以通过登录到您的拥入账户并点击您的配置图标和去Settings > API并创建一个新的个人访问标志, 存储在您的 github 秘密.R2_ACCOUNT_ID: Cloudflare R2仪表板的R2账户ID.R2_ACCESS_KEY_ID: R2从Cloudflare R2仪表板访问密钥ID.R2_SECRET_ACCESS_KEY: Cloudflare R2仪表板的R2秘密访问密钥.R2_BUCKET_NAME: Cloudflare R2仪表板上的R2桶名.
- 在您的仓库中添加以下环境变量:
PROJECT_NAME: 在您的环境变量中添加工程名称, 用于 Cloudflare R2 文件夹名称进行翻译 .CROWDIN_BRANCH_NAME: 为您的 Crowtin 项目添加分支名称, 以区分基于环境的翻译, 这需要放入环境变量, 而不是秘密, 因为软件包的消费者在定义时需要它cdnUrl以便查阅翻译.
- 设置 github 动作以同步对 CDN 的翻译, 请参考 同步翻译 详细情况.
通过运行安装软件包 :
npm install @deriv-com/translations
设置
- 通过导入和调用初始化主要组成部分的翻译
initializeI18n在组件函数之外. - 将返回值传递到
TranslationProvider构成部分从@deriv-com/translations。 。 。 . - 将默认语言传递到
TranslationProvider组件.
import { initializeI18n, TranslationProvider } from '@deriv-com/translations';
...
const i18nInstance = initializeI18n({ cdnUrl: 'https://cdn.example.com' })
const App = () => {
...
return (
<TranslationProvider defaultLang={'EN'} i18nInstance={i18nInstance}>
<App />
</TranslationProvider>
)
}
使用量
initializeI18n
这个 initializeI18n 函数初始化 i18next 与OTA SDK, react-i18next,还有语言探测器。 它需要一个带有 cdnUrl 属性的对象,这是存储翻译的 CDN URL .
import initializeI18n from "@deriv-com/translations";
initializeI18n({ cdnUrl: "https://cdn.example.com" });
- 对字符串使用任意一种
localize(...)或者说<Localize />。 。 。 .
Localize 组件示例 :
import { Localize } from "@deriv-com/translations";
<Localize
i18n_default_text="You cannot use your real money account with {{website_name}} at this time."
values={{ website_name }}
/>;
localize 示例:
注意
localize函数不会在资源加载或语言变化等任何变化发生后从 i18n 实例中获得更新。 这个localize函数将不用于将字符串包入组件,而只适合未更新字符串而不会引起问题的 util/mapper 函数.
import { localize } from "@deriv-com/translations";
const getNotification = () => ({
all: localize("all notifications"),
});
useTranslations 钩子
使用 Ctranslooks 钩子是一个自定义钩子, 它会在顶部添加一些更多的返回值 useTranslation 钩从 react-i18next。它可用于翻译组件中的字符串,切换应用程序的语言并查看当前语言等.
示例用法:
import { useTranslations } from "@deriv-com/translations";
const MyComponent = () => {
const { localize, switchLanguage, currentLang } = useTranslations();
const handleLanguageChange = () => {
switchLanguage(currentLang === "EN" ? "DE" : "EN");
};
return <p onClick={handleLanguageChange}>{localize("Change language")}</p>;
};
同步翻译
有一种github动作将 Crowdin 到CDN 的翻译同步.
行动包括:
PROJECT_SOURCE_DIRECTORY: 默认情况下您项目的源目录是src。 。 。 .CROWDIN_BASE_PATH: Crowdin 项目翻译的基础路径默认是.。 。 。 .CROWDIN_BASE_URL: 存储翻译的 CDN 的基础 URL,默认为https://api.crowdin.com。 。 。 .CROWDIN_BRANCH_NAME: 进行生产、试验或装配等.CROWDIN_PROJECT_ID: Crowdin 工程 ID 可以在群集工程设置中找到.CROWDIN_PERSONAL_TOKEN: Crowdin 个人代币,可以在众筹账户设置中找到.R2_ACCOUNT_ID: Cloudflare R2仪表板的R2账户ID.R2_ACCESS_KEY_ID: R2从Cloudflare R2仪表板访问密钥ID.R2_SECRET_ACCESS_KEY: Cloudflare R2仪表板的R2秘密访问密钥.R2_BUCKET_NAME: Cloudflare R2仪表板上的R2桶名.
参考动作文件 这里。 。 。 .
工作流程文件中动作的示例用途 :
在此路径中复制并粘贴您的仓库中的以下工作流程代码.github/workflows/sync_translations.yml。 。 。 .
name: Sync translations
on:
push:
branches:
- 'main'
schedule:
- cron: '0 */12 * * *'
jobs:
sync_translations:
runs-on: ubuntu-latest
steps:
- name: Sync translations
uses: deriv-com/translations/.github/actions/extract_and_sync_translations@master
with:
PROJECT_NAME: ${{ env.PROJECT_NAME }}
CROWDIN_BRANCH_NAME: ${{ env.CROWDIN_BRANCH_NAME }}
CROWDIN_BASE_URL: ${{ env.CROWDIN_BASE_URL }}
CROWDIN_BASE_PATH: ${{ env.CROWDIN_BASE_PATH }}
CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }}
CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}
R2_ACCOUNT_ID: ${{ secrets.R2_ACCOUNT_ID }}
R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
R2_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }}
R2_BUCKET_NAME: ${{ secrets.R2_BUCKET_NAME }}
与罗塞塔同步翻译
Crowdin正在退役 支持罗塞塔的内部翻译
API,它取代了慎之门.
extract_and_sync_translations_rosetta 是一个滴入的兄弟姐妹
Crowdin 动作: 它运行相同的提取器并上传相同的
translations/<locale>.json 文件到相同的 R2 文件夹,所以运行时间需要
无变化。 只有中间步骤不同——新弦由罗塞塔翻译
而不是从克罗丁下载.
如何稳定翻译 :
-
只有德尔塔. 当前
<locale>.json首先从CDN中获取,并且 用作翻译记忆。 键已经保留了逐字记录, 键没有 更长en.json被刷了,只有缺失的密钥被送到了Rosetta. 因为密钥是英文文本的crc32,所以重写字符串是新的密钥. -
被保护的标志.
{{placeholders}}, (中文(简体) ),<0>…</0>组件标记和任何 所列术语PROTECTED_TERMS_FILE(品牌和产品名称) 用于 HTML 令牌 Rosetta 保存、 事后恢复并核实出现 一次就是这样 检查失败的字符串, 或者其翻译仍然坚守 源代码没有的 HTML 实体,从文件中删除 运行时间回落为英语 任务摘要中列出. -
部分结果. 如果罗塞塔语失败了, 成功的地方 已发布,失败的 locale 的文件将保留为 CDN 的 标记失败 之后 上传,网站才能继续工作.
-
干跑动. 与
DRY_RUN: "true"作为工作流程附上目录 文物而不是被上传; 用于每次运行的第一次运行 将文物与现场文件相对照 一定要保证 第一个运行包括几个新字符串&, (中文(简体) ),<,引用和a{{x}}占位符,以及以占位符或标记开头的占位符(例如:{{count}} items),所以门的处理 他们的处理在一切之前 现予公布. -
何等为所译. CDN 上的任何字符串值都是 被再用,包括一个与英语相同的. 这是故意的(产品) 诸如"Wallet API"等名称被故意用英语保留,但也意味着 未翻译的密钥一旦发布,就永远不会怨恨; 从 cDN 文件需要翻译.
-
审查数值介于环境之间. 与
FALLBACK_ENVIRONMENT: staging关于生产同步,关键产品 缺少在中转目录中取出数值(所审查的QA) 罗塞塔被问到;等键表示等同英语,因为键是 Crc32 的 文本。 翻译:.FALLBACK_MODE: prefer更进一步:中转值也替换 一种不同的生产方式已经存在了,所以两个目录都汇合了起来. A 类 中转值必须通过同一占位符、标记和保护期检查 (b) 未在工作摘要和 关键在于生产本身的价值(偏好)或Rosetta的价值(偏差). 只装配的密钥从未添加过,生产密钥也不再包含en.json仍然被压抑. -
更正通过拉取请求.
OVERRIDES_FILEjSON 点数 在您的仓库中的文件, 由 locale 键入, 然后由 英文 源代码 :{ "fr": { "1 Change": "1 modification" }, "es": { "Edited {{time}} ago": "Editado hace {{time}}" } }征服者战胜了所有来源, 在每一个环境通过 文档。 无法进行符号检查的条目无法运行, 即使运行 不以语言为对象,而以两次命名的语言也是如此(
zh-CN财务报告和审定财务报表zh_cn- 其条目 英语不再被取出( 字符串被重写或去除) 为 在任务摘要中跳出并列出,所以删除或更新.
行动包括:
PROJECT_NAME, (中文(简体) ),PROJECT_SOURCE_DIRECTORY, (中文(简体) ),R2_ACCOUNT_ID, (中文(简体) ),R2_ACCESS_KEY_ID, (中文(简体) ),R2_SECRET_ACCESS_KEY, (中文(简体) ),R2_BUCKET_NAME: 至于克罗丁行动.ENVIRONMENT数字 :staging或者说production——R2子文件夹(什么CROWDIN_BRANCH_NAME也是为了这个.TARGET_LOCALES:逗号分出地语代码来翻译,例如.es,fr,pt。 。 。 . 中文也接受运行时间zh_cn编号 :zh_tw(单位:千美元)ZH_CN编号 :ZH_TW语言 密码,文件保留着这个名字.ROSETTA_API_TOKEN: 为罗塞塔(一个秘密)的"熊"(Bearer sorder). 创建时间 rosetta 网络应用( 请Rosetta 团队访问); 它只显示一次 .ROSETTA_API_BASE:Rosetta API的基础URL:仅由它的https主机,来自Rosetta团队. 需要,没有默认,所以消费者总是给寄出信物的主机取名.ROSETTA_CF_ACCESS_CLIENT_ID, (中文(简体) ),ROSETTA_CF_ACCESS_CLIENT_SECRET: 可选云旗 CI跑者访问服务符;参见"跑者网络".CDN_BASE_URL: 提供当前目录的地方(默认)https://translations.deriv.com) (中文(简体) ).PROTECTED_TERMS_FILE: JSON 数组字符串的可选路径, 绝对不能被翻译 .FALLBACK_ENVIRONMENT: 可选staging或者说production,另一个环境的目录在罗塞塔之前被查阅. 必须不同于ENVIRONMENT。 。 。 .FALLBACK_MODE数字 :missing(默认)只对此环境所缺少的密钥使用倒计时;prefer还让它取代了这个环境本身的价值观.OVERRIDES_FILE: 已审校的可选路径,形状{"<locale>": {"<English text>": "<translation>"}}。 。 。 .DRY_RUN数字 :true来写一件艺术品,而不是上传.
它暴露出四项产出: status (单位:千美元)noop 当目录不变的时候,
completed 当新翻译、倒置、 覆盖或修补更改时
他们,或 partial, (中文(简体) ), kept_back (符号留下的字符串数)
检查或为所剩的 HTML 实体, from_fallback (数值取自 FALLBACK_ENVIRONMENT和
overridden (价值) OVERRIDES_FILE 更改或添加; 已覆盖
已公布的重新使用计数).
将动作固定为 SHA 的释放承诺(…_rosetta@<sha> # v1.x.y更喜欢
比起来 @masterCrowdin和Rosetta的动作 运行他们的脚本
自己的承诺,与依赖 从该承诺 package-lock.json,永远
安装 @deriv-com/translations 从npm。 所以针也覆盖了取出器
和运行与 ROSETTA_API_TOKEN不只是动作的步骤.
(被贬去的道由活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活
运行者网络
罗塞塔 API 可能需要 Cloudflare 访问 服务符号 从 CI 调取 赛跑者。 若罗塞塔团队为GitHub Actions发行一款,则通过如下方式:
ROSETTA_CF_ACCESS_CLIENT_ID:指使牌的客户端ID(存储为秘密).ROSETTA_CF_ACCESS_CLIENT_SECRET:指使牌的客户端秘密(一个秘密).
两者均设或无;它们作为 CF-Access-Client-Id 财务报告和审定财务报表
CF-Access-Client-Secret 每一个罗塞塔的要求都写着头条 从来没有记录过.
没有他们,一个被阻挡的跑步失败
Rosetta submit was blocked by Cloudflare (HTTP 403, Ray ID …) 或者说
… redirected to Cloudflare Access login。如果一个带有标志的跑步仍然
与罗塞塔队私下分享错误的雷ID.
远离 Makima 动作
在此重命名之前, 动作是 extract_and_sync_translations_makima,与
页:1 MAKIMA_API_KEY 财务报告和审定财务报表 MAKIMA_API_BASE 投入和 deriv-makima-sync
{\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}真岛在2026年11月18日落地了 移动,改变 uses: 路径到
extract_and_sync_translations_rosetta,被钉在一个释放 包含
文件夹, 通过 ROSETTA_API_TOKEN 财务报告和审定财务报表 ROSETTA_API_BASE (罗塞塔API主机)
只有罗塞塔队的球员 跑
先干一场 在安装任何设备前检查设置:
基础必须是没有路径的 https 主机 .
2026年11月18日真麻关机前,老道还行:通了通
v1.6.1行动并警告。 日出后的首次发布计划
把它变成一个只用指针失败的步骤。 这个 deriv-makima-sync
bin 仅以指针失败到 deriv-rosetta-sync。 。 。 .
直接装入脚本的重播器 src/scripts/deriv-rosetta-sync.cjs, (中文(简体) ),
地点 makimaNameFor 现在 languageNameFor 财务报告和审定财务报表 buildSummary 带
rosettaErrors 改为 makimaErrors。 。 。 .
工作流程文件中罗塞塔动作的示例用途 :
name: Sync translations
on:
push:
branches:
- 'main'
schedule:
- cron: '0 */12 * * *'
# Two runs reading the same CDN snapshot would both upload, last writer wins;
# serialise them.
concurrency:
group: sync-translations-rosetta
cancel-in-progress: false
jobs:
sync_translations:
runs-on: ubuntu-latest
steps:
- name: Sync translations
# Pin the release commit; never @master (see above).
uses: deriv-com/translations/.github/actions/extract_and_sync_translations_rosetta@<release-commit-sha> # v1.x.y
with:
PROJECT_NAME: ${{ vars.R2_PROJECT_NAME }}
PROJECT_SOURCE_DIRECTORY: './src'
ENVIRONMENT: staging
TARGET_LOCALES: es,fr,pt
ROSETTA_API_TOKEN: ${{ secrets.ROSETTA_API_TOKEN }}
ROSETTA_API_BASE: ${{ vars.ROSETTA_API_BASE }}
ROSETTA_CF_ACCESS_CLIENT_ID: ${{ secrets.ROSETTA_CF_ACCESS_CLIENT_ID }}
ROSETTA_CF_ACCESS_CLIENT_SECRET: ${{ secrets.ROSETTA_CF_ACCESS_CLIENT_SECRET }}
R2_ACCOUNT_ID: ${{ secrets.R2_ACCOUNT_ID }}
R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
R2_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }}
R2_BUCKET_NAME: ${{ secrets.R2_BUCKET_NAME }}
同一站台可在本地运行, 之后进行干燥运行 npx deriv-extract-translations ./src数字 :
PROJECT_NAME=my-project ENVIRONMENT=staging TARGET_LOCALES=es,fr,pt \
ROSETTA_API_BASE=https://<rosetta-api-host> ROSETTA_API_TOKEN=… DRY_RUN=true npx deriv-rosetta-sync
捐款
欢迎捐款。 请随您的更改打开拉动请求 .