Yaak 多语言:4个改动点实现不重启的界面语言实时切换
【免费下载链接】yaakThe most intuitive desktop API client. Organize and execute REST, GraphQL, WebSockets, Server Sent Events, and gRPC 🦬项目地址: https://gitcode.com/GitHub_Trending/ya/yaak
Yaak 是一款覆盖 REST、GraphQL、gRPC 等协议的桌面 API 客户端,界面文本目前全部硬编码为英文。本文解决 Yaak 多语言问题:新增 2 个语言包、改动 4 处代码,让界面语言可以实时切换、重启后依然保持。
完成后的效果
做完后,你可以在 Yaak 的设置页选择界面语言,切换后界面立即变为所选语言,无需重启应用,选择也会跨重启保留。
前置条件
- Node.js 20 及以上,能在 apps/yaak-client/ 下跑起前端
- 熟悉 React 与 jotai 基础(Yaak 用 jotai 管理前端状态)
- 不需要安装任何新依赖,全部基于项目已有组件与工具
- 工作目录为仓库根目录,改动只涉及前端应用
🧩 分步实施
建好语言包目录
翻译资源放在前端应用目录下,与源码隔离,方便后续按需扩展语言。新建 locales 目录,放两个 JSON 文件即可,其他语言文件后面再加。
apps/yaak-client/ └── locales/ ├── en.json └── zh-CN.json文件内容采用两级分组,key 用点路径引用(如common.send),后续加语言时只需照抄结构:
{ "common": { "send": "发送", "cancel": "取消", "save": "保存" }, "settings": { "general": "常规", "language": "界面语言" } }en.json存英文原文,zh-CN.json存译文,两边 key 必须一一对应,否则切换后会出现空白。
建好语言状态与翻译 Hook
Yaak 的设置项状态集中在 lib/atoms.ts,语言选择也放这里。项目已有atomWithKVStorage工具做本地持久化,用它代替普通atom,重启才不丢选择。
// apps/yaak-client/lib/atoms.ts(在文件内追加) // 走 KV 持久化而不是内存 atom,应用重启后语言选择不丢失 export const languageAtom = atomWithKVStorage<string>("ui_language", "en");翻译 Hook 单独成文件,所有组件只调用t(key),不直接碰 JSON,这样以后换 i18n 库只需改这一处。
// apps/yaak-client/hooks/useTranslation.ts import { useAtom } from "jotai"; import { languageAtom } from "../lib/atoms"; import en from "../locales/en.json"; import zhCN from "../locales/zh-CN.json"; const LOCALES = { en, "zh-CN": zhCN } as const; // 所有读取该 atom 的组件都会随语言变化自动重渲染, // 这是不重启切换的关键 export function useTranslation() { const [language] = useAtom(languageAtom); const dict = LOCALES[language] ?? en; return { language, // 缺失 key 时回退为 key 本身,肉眼即可发现漏翻的文案 t: (key: string) => (key.split(".").reduce((o: any, k) => o?.[k], dict) ?? key), }; }在设置页加好 Yaak 多语言选项
通用设置页在 SettingsGeneral.tsx,它内部的SettingRowSelect就是下拉行控件,语言选项直接挂进去即可,不用另造组件。
下面把该文件的多处修改合并展示:引入 atom、在组件内订阅、新增 Localization 分组。
// apps/yaak-client/components/Settings/SettingsGeneral.tsx import { useAtom } from "jotai"; import { languageAtom } from "../../lib/atoms"; export function SettingsGeneral() { const settings = useAtomValue(settingsAtom); const [language, setLanguage] = useAtom(languageAtom); // ……(组件原有逻辑省略) return ( <SettingsList className="space-y-8"> <SettingsSection title="Localization"> <SettingRowSelect title="Interface Language" description="切换界面语言,保存后立即生效,无需重启" name="language" value={language} onChange={setLanguage} options={[ { label: "English", value: "en" }, { label: "简体中文", value: "zh-CN" }, ]} /> </SettingsSection> {/* ……(其余设置分组省略) */} </SettingsList> ); }注意这里用本地 atom 而不是patchModel:语言是纯前端偏好,不该动后端数据模型,这样也避免了 Rust 侧 schema 改动。
替换硬编码文本为翻译调用
界面变中文的最后一公里,是把组件里的英文字符串换成t()调用。先从高频可见的标题改起:
// 改造前 <Heading>General</Heading> // 改造后 <Heading>{t("settings.general")}</Heading>逐个找文本太慢,可以先用命令列出组件里的硬编码英文,再按出现频率排优先级:
grep -rn 'title="[A-Z][a-z]' apps/yaak-client/components --include='*.tsx'替换时保持语言包 key 稳定:同一句英文永远对应同一个 key,避免general和General并存造成漏翻。
🐛 常见报错与修复
现象:切换语言后部分界面仍是英文。原因:对应组件没接useTranslation,文本仍是硬编码。修复:在该组件补上调用即可。
import { useTranslation } from "../hooks/useTranslation"; const { t } = useTranslation(); // 把目标文本替换为 {t("common.send")}现象:设置页语言下拉框出现红色边框。原因:value不在options列表里,比如语言包用了zh_CN而选项写的是zh-CN。修复:统一两边命名,以 atom 默认值en的格式为准。
现象:重启应用后语言退回英文。原因:用了普通atom,状态只存在内存。修复:换成项目现成的atomWithKVStorage,见步骤二。
✅ 验证清单
- 设置页出现语言选项,切换后当前窗口立即变为目标语言
- 中/英来回切换,界面无空白区域,控制台无 key 报错
- 重启应用后,语言选择仍然保留
- 开发模式下运行前端,类型检查与构建均无报错
以上步骤走通后,Yaak 多语言的不重启切换已经落地,下一步建议按同样模式继续替换侧边栏和响应面板的文案。
【免费下载链接】yaakThe most intuitive desktop API client. Organize and execute REST, GraphQL, WebSockets, Server Sent Events, and gRPC 🦬项目地址: https://gitcode.com/GitHub_Trending/ya/yaak
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考