为 Zensical 网站添加多语言翻译本文基于当前本站正在使用的硅基流动 Qwen3-8B 客户端翻译系统glm-config.jsglm-translate.js整理而成。只要按步骤接入你就能获得和wcowin.work一样的多语言体验。功能概述客户端翻译不改动原文只在浏览器端把页面上的中文动态翻译成目标语言多语言切换通过顶部的「语言切换」菜单在中文 / 英文 / 日文 / 其他语言之间切换两种模式仅当前页面翻译全站翻译记住你的语言偏好后续页面自动翻译缓存与记忆页面级翻译缓存同一页面再次访问时可快速恢复本地缓存常见文本减少二次请求与 Ask AI 共用后端翻译与 Ask AI 聊天都走硅基流动 OpenAI 兼容接口 Qwen/Qwen3-8B共用同一个GLM_API_KEY通过 GitHub Actions Secrets 注入!!! warning “SEO 提醒”这种方案属于运行时客户端翻译- 对访问者来说是多语言网站- 对搜索引擎来说仍然是单语言内容索引的是构建时的中文如果你追求多语言 SEO需要用「多语言内容预生成」的方式本文不展开。1. 准备工作1.1 一个已经跑起来的 Zensical 站点假设你已经有了一个基本可运行的 Zensical 项目zensical.toml docs/目录结构。如果需要完整参考实现可以直接查看我的开源仓库仓库地址Wcowin/Wcowin.github.io与翻译相关的核心文件docs/javascripts/glm-config.jsdocs/javascripts/glm-translate.js可以直接复制这两个文件到你的项目里再按本文做少量配置即可。1.2 硅基流动 API Key与 Ask AI 共用打开硅基流动控制台https://cloud.siliconflow.cn/注册 / 登录后在「API Key」页面创建一个 Key将它配置到 GitHub 仓库 Secrets 中下一节会用到这个 Key 同时会被Ask AI 聊天组件(chat-widget.js) 使用多语言翻译系统(glm-config.js glm-translate.js) 使用2. 引入翻译脚本与配置2.1 复制核心脚本文件在你的项目中创建或直接复制仓库里的版本docs/javascripts/glm-config.js翻译系统的「全局配置」包括接口地址、模型名、跳过哪些元素、术语表、UI 配置等当前已配置为window.GLM_CONFIG{api:{endpoint:https://api.siliconflow.cn/v1/chat/completions,model:Qwen/Qwen3-8B,// ...},// ...};docs/javascripts/glm-translate.js实现整个翻译流程文本收集、批量调用 API、缓存、进度提示、页面/全局翻译模式等内部通过window.GLM_API_KEY拿到密钥并使用GLM_CONFIG.api.endpoint / api.model发起请求推荐做法直接从仓库复制这两个文件后续如果我优化了实现你也可以轻松diff更新。2.2 在 zensical.toml 中引入脚本和样式确保在zensical.toml里已经包含以下配置你的项目可以按需精简下面是与翻译 / Ask AI 相关的部分[project] # 额外的 JavaScript 文件 extra_javascript [ javascripts/glm-config.js, # 翻译系统配置Qwen3-8B 跳过规则等 javascripts/glm-translate.js, # 翻译主逻辑 javascripts/glm-api-config.js, # API Key 注入由本地或 CI 生成 javascripts/chat-widget.js, # Ask AI 聊天组件可选 ] # 额外的 CSS 文件 extra_css [ stylesheets/chat-widget.css, # Ask AI 样式与翻译的进度/Toast 视觉统一 ]这里最关键的有三点glm-config.js和glm-translate.js要在页面上加载glm-api-config.js必须在翻译脚本之前加载提供window.GLM_API_KEY如果你不需要 Ask AI可以先去掉chat-widget.js与对应 CSS3. 通过 GitHub Actions Secrets 注入 API Key3.1 仓库 SecretsGLM_API_KEY在你的仓库中打开Settings→Secrets and variables→Actions新建一个 SecretNameGLM_API_KEYValue硅基流动生成的 API Key注意变量名仍然叫GLM_API_KEY只是一个名字实际已经指向硅基流动。3.2 Actions 里生成glm-api-config.js在.github/workflows/docs.yml中类似下面这样配置与你当前仓库保持一致-name:Generate GLM API Configrun:|echo window.GLM_API_KEY ${{ secrets.GLM_API_KEY }}; docs/javascripts/glm-api-config.js这样仓库里不会保存明文密钥构建时自动生成glm-api-config.js浏览器运行时可以通过window.GLM_API_KEY获取 KeyAsk AI 与翻译都会用同一个 Key 与模型3.3 .gitignore 中忽略glm-api-config.js# 自动生成的 API 配置文件包含敏感信息 docs/javascripts/glm-api-config.js4. 在 Zensical 中配置多语言切换菜单Zensical底层仍是 Material for MkDocs通过project.extra.alternate来渲染顶栏的语言切换菜单。在zensical.toml中已经有类似配置# 多语言切换配置 [[project.extra.alternate]] name 中文 link #glm-translate-chinese_simplified lang zh [[project.extra.alternate]] name English link #glm-translate-english lang en # [[project.extra.alternate]] # name 日本語 # link #glm-translate-japanese # lang ja含义说明name菜单上显示的文字lang供浏览器 / SEO 使用的语言代码link特殊格式的锚点#glm-translate-{language_key}glm-translate.js在初始化时会监听所有链接的点击事件// 例点击 link#glm-translate-english// 会解析出 language_key english// 然后调用window.translateTo(language_key);可用的language_key与内部语言映射在GLM_CONFIG.languages中定义例如chinese_simplifiedenglishjapanesekoreanfrenchspanishgermanarabicdeutschportuguese要新增一种语言只需要确认GLM_CONFIG.languages里存在对应 key在project.extra.alternate里再添加一项例如日语[[project.extra.alternate]] name 日本語 link #glm-translate-japanese lang ja5. 翻译系统的工作原理基于你当前的实现这一节是“理解型”不用写代码但有助于调试和自定义。5.1 入口window.translateTo(language)所有语言切换最终都会调用window.translateTo(language)它会弹出一个「选择翻译范围」弹窗当前页面 / 全局翻译根据选择调用translatePage(language, showProgress)如选择全局会在localStorage里写入glm_global_translation_preference5.2 翻译策略文本收集使用TreeWalker遍历document.body文本节点只收集「包含中文」的文本对代码块、页脚、导航、大量符号等通过GLM_CONFIG.detection.skipTags / skipSelectors做了专门过滤批量调用 Qwen3-8B按BATCH_SIZE分批每批再拆给两个“虚拟 API 通道”并行调用请求使用POSThttps://api.siliconflow.cn/v1/chat/completions{model:Qwen/Qwen3-8B,messages:[{role:system,content:... 翻译规则 ...},{role:user,content:翻译指令 文本}]}缓存与页面记忆翻译结果会被写入translationCache内存每个页面还有独立的pageTranslationCache用于在即时导航 / 返回时快速恢复全局偏好glm_global_translation_preference则控制“新页面是否自动翻译”5.3 UI 与用户体验右下角会有与 Ask AI 按钮风格统一的翻译进度 ToastCollecting text.../Translation completed! 55 texts translated等通过ProgressManager和showTranslateStatus控制再次点击语言切换时如果目标语言与当前一致会给出「当前已是 English」等提示避免重复请求。6. 与 Ask AI 的关系你现在站点上的两套智能功能共用一套后端与密钥Ask AI 聊天组件docs/javascripts/chat-widget.js使用window.GLM_API_KEYQwen/Qwen3-8B完成问答多语言翻译系统glm-config.js glm-translate.js同样使用window.GLM_API_KEYQwen/Qwen3-8B批量翻译页面文本好处计费统一好管理只需要维护一处 Secrets (GLM_API_KEY) 与一条 Actions 注入逻辑7. 常见问题7.1 点击语言切换没有反应检查以下几点zensical.toml里是否配置了extra_javascript尤其是glm-translate.js浏览器控制台是否有报错例如GLM_CONFIG is not definedproject.extra.alternate中link是否是#glm-translate-xxx这种格式7.2 提示「未找到翻译用的 API 密钥」确认GitHub Secrets 中已经有GLM_API_KEYActions 工作流里确实有生成glm-api-config.js的步骤浏览器控制台里window.GLM_API_KEY不是undefined7.3 翻译完某些代码/公式被破坏了优先在页面模板或 Markdown 中给这类元素加上spanclassno-translate.../span或在GLM_CONFIG.detection.skipSelectors中增加更精确的 CSS 选择器8. 小结按照本文步骤你就可以在 Zensical 网站中获得顶栏语言切换当前页面 / 全站两种翻译模式Qwen3-8B 驱动的高质量翻译与 Ask AI 共用一套后端与密钥的统一架构如果你需要对这套翻译系统做更深入的定制例如只翻译正文、接入别的 LLM、改成后端代理可以直接阅读并修改docs/javascripts/glm-config.jsdocs/javascripts/glm-translate.js源码始终以仓库为准Wcowin/Wcowin.github.io。欢迎在 Issues 或评论里交流你的使用体验和改进想法。