ChatGPT-Midjourney 多语言国际化实战:为项目添加全新语言翻译的完整指南
人工智能AI 应用前端媒体生成【免费下载链接】ChatGPT-Midjourney 一键拥有你自己的 ChatGPT众多AI 网页服务 | One click access to your own ChatGPTMany AI web services项目地址https://gitcode.com/gh_mirrors/ch/ChatGPT-Midjourney点击查看免费下载本文围绕 ChatGPT-Midjourney 仓库中的 docs/translation.md 展开系统讲解如何为该开源项目新增一种界面语言翻译的完整流程。你将从零开始学会复制基础语言文件、切换类型声明、注册语言到ALL_LANGS与ALL_LANG_OPTIONS、逐条翻译文案并理解背后的语言回退fallback机制与语言自动检测逻辑最终能独立提交一份可被作者合并的翻译 PR。一、前置认知项目国际化i18n架构概览在动手添加翻译之前先理解 ChatGPT-Midjourney 的语言体系是如何组织的。所有语言文件都存放在 app/locales/ 目录下目前已内置 19 种语言语言键文件语言键文件cncn.tseses.tsenen.tsitit.tstwtw.tstrtr.tsptpt.tsdede.tsjpjp.tsvivi.tskoko.tsruru.tsidid.tscscs.tsfrfr.tsnono.tsarar.tsbnbn.tssksk.ts其中 en.ts 是唯一使用完整LocaleType的基准语言文件其余语言文件如 jp.ts、ru.ts、ar.ts都使用PartialLocaleType。语言注册的中心在 app/locales/index.ts它负责集中import所有语言模块并组装成ALL_LANGS映射表通过ALL_LANG_OPTIONS提供每种语言在设置界面中的展示名称提供getLang()/changeLang()/getISOLang()等运行时 API在启动时把目标语言与回退语言英语做深合并缺词自动补英文。从源码结构看新增语言本质上是三步式改动新建语言文件 → 在 app/locales/index.ts 中注册 → 翻译文案。下面按 docs/translation.md 的官方步骤逐一展开。二、核心流程以新增语言new为例的完整 8 步原文档以假想语言new为例给出如下 8 个步骤。我们逐条拆解并补充源码依据。第 1 步复制基础语言文件cp app/locales/en.ts app/locales/new.ts以英文文件 app/locales/en.ts 为模板复制出new.ts。之所以选择en.ts而不是其他语言文件是因为它是唯一完整定义全部文案键的文件约 682 行包含所有嵌套对象与函数型字段作为翻译对照表最齐全。复制后先不要急着翻译先做第 2 步的类型改造否则 TypeScript 会在编译期报错。第 2 步改写类型声明与默认导出编辑new.ts把文件末尾的导出与类型声明改为// 修改前 const en: LocaleType { ... }; export default en; // 修改后 const new: PartialLocaleType { ... }; export default new;这里有两个关键点类型从LocaleType改为PartialLocaleType。两者的差异定义在 app/locales/cn.tstype DeepPartialT T extends object ? { [P in keyof T]?: DeepPartialT[P] } : T; export type LocaleType typeof cn; export type PartialLocaleType DeepPartialtypeof cn;LocaleType要求所有字段必须存在而PartialLocaleType把每个字段都变成可选。这意味着你允许在new.ts中只翻译部分文案——缺失的键会在运行时自动回退到英文不会导致界面出现空白。这也是 en.ts 顶部注释反复强调的原因if you are adding a new translation, please use PartialLocaleType instead of LocaleType新增翻译请使用PartialLocaleType而非LocaleType。导出方式。注意 index.ts 中的导入使用的是import new from ./new.ts这种 default 导入形式因此语言文件的默认导出必须是对应语言对象本身。第 3~6 步在语言注册中心登记编辑 app/locales/index.ts共四处改动// ① 在文件顶部 import 区新增 import new from ./new.ts; // ② 在 ALL_LANGS 对象中加入新键 const ALL_LANGS { cn, en, tw, pt, jp, ko, id, fr, es, it, tr, de, vi, ru, cs, no, ar, bn, sk, new, // 新增 }; // ③ 在 ALL_LANG_OPTIONS 中加入显示名称 export const ALL_LANG_OPTIONS: RecordLang, string { ... sk: Slovensky, new: new lang, // 新增这里应填写该语言的原生名称 };要点说明ALL_LANGS键名即语言代码它的keyof类型被导出为Lang联合类型见 app/locales/index.ts新增键会自动扩展Lang类型从而让getLang()、changeLang()、ALL_LANG_OPTIONS等强类型 API 立刻接受新语言。ALL_LANG_OPTIONS值是展示在下拉菜单中的语言名称惯例使用该语言的自称。观察现有条目可见规律如cn: 简体中文、en: English、ar: العربية、bn: বাংলা因此new也应填入对应语言的原生拼写。AllLangs由Object.keys(ALL_LANGS)自动生成见 app/locales/index.ts无需手动维护。它被 app/components/settings.tsx 中的语言下拉菜单遍历用于渲染选项Select value{getLang()} onChange{(e) { changeLang(e.target.value as any); }} {AllLangs.map((lang) ( option value{lang} key{lang} {ALL_LANG_OPTIONS[lang]} /option ))} /Select完成以上注册后新语言会自动出现在设置页面的语言选择器中用户无需任何额外配置即可切换。第 7 步翻译文案这是工作量最大的环节。逐条将new.ts中的英文文案翻译为目标语言。翻译时请特别留意以下四种特殊字段形态① 函数型字段保留函数签名只翻译返回的字符串。例如 en.ts 中的ChatItem: { ChatItemCount: (count: number) ${count} messages, }, Chat: { SubTitle: (count: number) ${count} messages, ... Input: (submitKey: string) { var inputHints ${submitKey} 发送; ... }, },翻译时保持(count: number) ...的签名与插值结构不变只替换引号内的文案例如中文版 cn.ts 写为(count: number) ${count} 条对话。② 内嵌 Markdown 链接的文案。如Error.Unauthorized字段的值中包含[Settings](https://link.gitcode.com/i/cd14212de9dbe472bd6874670be33b49)这类链接见 en.ts翻译时必须保留 Markdown 链接语法与路由地址只翻译链接文字否则前端渲染会破坏链接。③ 依赖isApp的环境分支。文件顶部有一行const isApp !!getClientConfig()?.isApp;它根据当前是否运行在桌面客户端Tauri 应用中为Error.Unauthorized等字段选择不同文案。翻译时要完整保留三元表达式结构仅替换两个分支里的字符串。④ 带占位符/动态内容的文案。注意类似PinToastContent: Pinned 1 messages to contextual prompts、Commands下以new、newm、next、prev、clear、del为键的快捷指令名以及设置页中各种带Title/SubTitle的嵌套对象都需要一并翻译保证整个界面语言统一。第 8 步提交 Pull Request完成翻译后提交 Pull Request作者审核合并后新语言即随下一版本发布。提交前建议自查运行yarn lint或npx tsc --noEmit确认类型检查通过未翻译的字段因PartialLocaleType可选不会报错但请勿把翻译文件里的类型误写为LocaleType确认 app/locales/index.ts 中ALL_LANGS与ALL_LANG_OPTIONS都已登记确认new.ts的 default 导出正确。三、理解背后的机制为什么缺词也能用新增语言之所以不需要翻译 100% 的文案就能上线得益于 app/locales/index.ts 中的回退合并逻辑const fallbackLang en; const targetLang ALL_LANGS[getLang()] as LocaleType; // if target lang missing some fields, it will use fallback lang string merge(fallbackLang, targetLang); export default fallbackLang as LocaleType;运行流程是先通过getLang()解析出当前语言再从ALL_LANGS取出对应的语言对象作为targetLang然后调用 app/utils/merge.ts 将targetLang的字段深合并进英文基准对象fallbackLang。合并后的对象作为默认导出供全项目通过import Locale from ./locales消费。merge的实现app/utils/merge.ts对每个键递归处理如果源值是对象则递归合并否则直接覆盖。因此目标语言中已翻译的键覆盖英文未翻译的键保留英文原文——这就是缺词自动补英文的机制保证也是 docs/translation.md 要求新语言文件使用PartialLocaleType的原因只有字段可选未翻译的键才不会被类型系统强制要求。四、语言自动检测与切换新语言如何被用户使用新语言注册后会参与到 app/locales/index.ts 的运行时逻辑中① 初次访问的自动检测getLanguage。index.ts 使用Intl.Locale解析浏览器语言优先检查地区代码如zh-CN的CN小写cn是否在AllLangs中其次检查语言代码如zh、en是否在AllLangs中均不命中则回退到默认语言en。这意味着新语言的键命名建议与 ISO 语言/地区代码保持一致例如简体中文用cn、繁体中文用tw更利于用户访问时被自动识别。② 用户手动切换changeLangexport function changeLang(lang: Lang) { setItem(LANG_KEY, lang); location.reload(); }选择结果写入localStorage的lang键并刷新页面下次进入时getLang()会优先读取该键见 index.ts。③ 输出 HTML 语言属性getISOLangexport function getISOLang() { const isoLangString: Recordstring, string { cn: zh-Hans, tw: zh-Hant, }; const lang getLang(); return isoLangString[lang] ?? lang; }cn/tw这类非标准代码会被映射为符合 HTMLlang属性标准的zh-Hans/zh-Hant其他语言直接返回自身键。该值被 app/components/home.tsx 用于设置页面的document.documentElement.lang影响屏幕阅读器与浏览器翻译功能——如果你的新语言有特殊书写方向如阿拉伯语ar的 RTL还可留意相关样式适配。五、实战验证清单按上述流程操作完成后建议按以下清单验证确保翻译可正常工作类型层面确认new.ts使用PartialLocaleType类型且 default 导出正确tsc --noEmit通过注册层面确认 app/locales/index.ts 的 import、ALL_LANGS、ALL_LANG_OPTIONS三处均已改动运行时层面启动开发服务yarn install yarn dev在设置页语言下拉菜单中找到新语言并切换刷新后确认界面文案生效回退层面有意漏译某个键如WIP确认界面该处显示英文而非空白验证 merge 回退机制特殊字段层面检查Input这类函数型文案、Error.Unauthorized这类含 Markdown 链接的文案、以及isApp分支文案显示是否正常。六、常见问题速查Q1翻译文件里个别键忘了翻译会编译报错吗不会。只要类型是PartialLocaleType所有字段均为可选未翻译的键运行时回退为英文。但若误用LocaleType类型TypeScript 会强制要求补全所有键。Q2新增语言后设置页没有出现该语言选项检查是否漏改了 app/locales/index.ts 中的ALL_LANGS或ALL_LANG_OPTIONS。AllLangs由ALL_LANGS自动派生无需单独维护语言选择器直接遍历AllLangs与ALL_LANG_OPTIONS见 app/components/settings.tsx。Q3语言键命名有什么讲究从 index.ts 的自动检测逻辑看键名应尽量贴近 ISO 语言/地区代码如pt、vi、ar这样用户首次访问时更可能被自动匹配非标准代码如cn、tw需要靠getISOLang()的映射表转换为标准值。Q4可以只翻译部分常用界面吗可以。得益于PartialLocaleType merge 回退机制先翻译高频区域Auth、Chat、Settings等即可让新语言可用后续再逐步补齐其余文案无需一次性完成全部翻译。赞分享人工智能AI 应用前端媒体生成【免费下载链接】ChatGPT-Midjourney 一键拥有你自己的 ChatGPT众多AI 网页服务 | One click access to your own ChatGPTMany AI web services项目地址https://gitcode.com/gh_mirrors/ch/ChatGPT-Midjourney点击查看免费下载相关推荐tui.editor国际化翻译完整指南为开源编辑器添加新语言包tui.editor国际化翻译完整指南为开源编辑器添加新语言包 TOAST UI Editor 是一款功能强大的开源 Markdown 编辑器支持多种语言国前端UI组件如何用Rust构建键盘记录器Rust-for-Malware-Development实战教程如何用Rust构建键盘记录器Rust for Malware Development实战教程 在网络安全领域键盘记录器Keylogger是一种重要的监控如何为noVNC添加新语言支持完整国际化指南如何为noVNC添加新语言支持完整国际化指南 noVNC作为一款流行的HTML5 VNC客户端支持多语言国际化功能让全球用户能够以自己熟悉的语言使用该工具前端音视频上一篇今日热门项目推荐PhalApi - 让PHP接口开发更高效优雅下一篇妙言MiaoYan最佳实践10个技巧构建高效个人知识管理系统创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

Rocky|NTP服务

Rocky|NTP服务

服务端vi /etc/chrony.conf :编辑指定目录文件pool 2.pool.ntp.org iburst 《将2.pool.ntp.org改为自己的ip#Use NTP servers from DHCP.sourcedir /run/chrony-dhcp#Record the rate at which the system clock gains/losses time.driftfile /var/lib/chrony/d…

2026/10/11 9:46:02 阅读更多 →
题解:洛谷 P1047 [NOIP 2005 普及组] 校门外的树

题解:洛谷 P1047 [NOIP 2005 普及组] 校门外的树

本文分享的必刷题目是从蓝桥云课、洛谷、AcWing等知名刷题平台精心挑选而来,并结合各平台提供的算法标签和难度等级进行了系统分类。题目涵盖了从基础到进阶的多种算法和数据结构,旨在为不同阶段的编程学习者提供一条清晰、平稳的学习提升路径。 欢迎大家订阅我的专栏:算法…

2026/10/9 14:28:13 阅读更多 →
题解:洛谷 P1088 [NOIP 2004 普及组] 火星人

题解:洛谷 P1088 [NOIP 2004 普及组] 火星人

本文分享的必刷题目是从蓝桥云课、洛谷、AcWing等知名刷题平台精心挑选而来,并结合各平台提供的算法标签和难度等级进行了系统分类。题目涵盖了从基础到进阶的多种算法和数据结构,旨在为不同阶段的编程学习者提供一条清晰、平稳的学习提升路径。 欢迎大家订阅我的专栏:算法…

2026/10/9 14:28:13 阅读更多 →

最新新闻

微信小程序投票系统毕设源码与数据库实战指南

微信小程序投票系统毕设源码与数据库实战指南

简介:这是一套面向计算机专业本科生的高分毕业设计级微信小程序源码,聚焦在线投票系统开发,适用于毕业设计、课程设计与期末大作业等实践场景。资源包含完整可运行的前后端代码及配套数据库,经本地编译验证,评审得分高…

2026/10/11 9:46:49 阅读更多 →
rea工具集:搞定批量重命名、代码重构与文件整理

rea工具集:搞定批量重命名、代码重构与文件整理

如果你和我一样,经常要在一堆旧项目里做重复的机械变更——批量改名、重整目录、统一日志格式、扫出废弃的重复代码……你可能也会需要一个 “rea”。这不是什么新框架,是我花了几周实际打磨、又在上百个文件规模的项目里反复跑过才敢拿出来说的工具集合…

2026/10/11 9:46:49 阅读更多 →
Copilot代码审查三大盲区与对策:AI生成代码如何把关

Copilot代码审查三大盲区与对策:AI生成代码如何把关

1. 项目现象与问题拆解:提效背后的"烂摊子"1.1 为什么提效300%却留下技术债?——从代码库的真实变化说起先说个真实感受。上上个季度,团队引入辅助编程工具之后,交付速度肉眼可见地起飞。以前一个中等复杂的接口要从设计…

2026/10/11 9:46:49 阅读更多 →
正则表达式工程化实践:从引擎原理到日志解析与性能优化

正则表达式工程化实践:从引擎原理到日志解析与性能优化

如果你只给我“rea”这个项目代号,我大概率会把它理解成正则表达式(Regular Expression)的内部缩写——这也是不少团队在技术方案里惯用的叫法。在我处理日志抽取、接口字段校验、数据清洗和定时任务里的文本规则时,正则表达式几乎…

2026/10/11 9:46:49 阅读更多 →
impeccable项目:构建无可挑剔的数字产品交付质量标准体系

impeccable项目:构建无可挑剔的数字产品交付质量标准体系

1. 一个词引发的项目灵感:为什么是“impeccable”第一次看到“impeccable”这个词,是在一份设计评审的反馈意见里。当时一位资深设计负责人给一个交互稿的批注只有这一个词,没有具体修改意见,没有标注问题点,就写了“i…

2026/10/11 9:46:49 阅读更多 →
ADHD执行功能解析:从神经机制到工作流适配

ADHD执行功能解析:从神经机制到工作流适配

1. “I have ADHD”不是一句网络梗,而是一把打开理解之门的钥匙最近在多个内容平台刷到带#IHaveADHD标签的短视频,画面里有人一边语速飞快地拆解三重嵌套的Excel公式,一边突然盯着窗外飘过的云发呆两分钟;有人刚把咖啡杯放回桌面就…

2026/10/11 9:45:48 阅读更多 →

日新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/11 0:00:27 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/11 0:00:27 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 5:23:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 21:32:20 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 10:38:42 阅读更多 →