GitHub Actions自动化多语言HTML部署的核心是将翻译嵌入CI流程:源HTML用data-i18n标记,配合locales/*.json语言包,通过Node脚本生成dist/zh/、dist/en/等带子目录的静态页,并自动注入双向hreflang标签、校验JSON键名一致性与BCP 47格式,失败即阻断发布。

怎么用 GitHub Actions 自动化生成多语言 HTML 文件
静态站多语言部署的核心不是“翻译完再上传”,而是把翻译动作变成 CI 流程里的一环。只要源语言 HTML 和语言包 JSON 齐备,就能在每次提交后自动生成所有语言版本的页面文件。
常见错误现象:手动导出翻译、本地 zip 压缩、FTP 上传——漏传一个 ja/index.html 就导致日语用户看到 404;或语言包更新了但没 rebuild,线上仍是旧文案。
- 源语言 HTML 必须是纯模板:所有文案用
data-i18n标记,不写死中文/英文文本;<h1 data-i18n="home.title"></h1>是标准写法 - 每种语言一个 JSON 文件,路径固定为
locales/zh.json、locales/en.json、locales/ja.json,键名完全对齐 - GitHub Actions 脚本里用 Node.js 脚本(如
i18n-build.js)读取模板 HTML,遍历所有[data-i18n]元素,按当前语言 JSON 替换textContent和placeholder等属性 - 生成目标路径必须带语言子目录:
dist/zh/index.html、dist/en/index.html,不能平铺在dist/下,否则路由冲突 - 脚本执行前先校验所有 JSON 是否合法:
JSON.parse()+ 键名比对,缺 key 或格式错就exit 1中断流程,避免部署残缺包
为什么不能靠 i18next 的前端动态加载来替代静态部署
前端 JS 动态加载语言包(比如 i18next.init({ lng: 'ja', resources: { ... } }))适合 SPA,但对 SEO 和首屏性能有硬伤——搜索引擎爬虫不等 JS 执行完就抓取,结果只看到空 <h1 data-i18n="home.title"></h1>,页面无文本内容。
使用场景:管理后台、登录页等无需 SEO 的内部系统可以接受;但面向公众的产品官网、文档站、营销页必须输出真实 HTML 文本。
立即学习“前端免费学习笔记(深入)”;
- Googlebot 不执行
fetch(),也不会等i18next.changeLanguage('zh')完成后再截图 - 即使加了
prerender.io或 SSR,也增加运维复杂度,不如直接生成静态文件可靠 - CDN 缓存的是最终 HTML,不是 JSON + JS 组合,前者缓存命中率高、TTFB 低;后者每次都要 JS 解析+DOM 操作,移动端卡顿明显
- 如果某语言包加载失败(如
locales/ko.json404),前端页面直接留白;而静态部署失败会阻断整个 CI,你立刻收到通知,不会让坏版本上线
hreflang 标签怎么和自动化部署联动才不出错
<link rel="alternate" hreflang="zh-CN" href="https://example.com/zh/"> 这类标签必须静态写死在每个语言版本的 <head> 里,且要双向闭环——中文页要声明英文页,英文页也要声明中文页。JS 动态插入或漏写一条,Google 就忽略整组语言关系。
自动化部署时最容易翻车的是 hreflang 的 URL 生成逻辑:绝对路径拼错、漏掉 trailing slash、协议不一致(HTTP vs HTTPS)都会让爬虫认为链接失效。
- CI 脚本生成
dist/zh/index.html时,自动注入全部<link rel="alternate">,包括自己:hreflang="zh"对应href="https://example.com/zh/" - href 值必须是完整绝对 URL,从环境变量读取
BASE_URL=https://example.com,拼接为${BASE_URL}/zh/,不能用相对路径 - 所有语言版本的 hreflang 列表必须完全一致(含顺序),用同一份配置数组生成,避免某语言页少写一条
hreflang="x-default" - 生成后运行校验脚本:检查
dist/*/index.html中是否每个都有hreflang="x-default",且所有hreflang值符合 BCP 47(如zh-Hans✅,zh_CN❌)
语言包更新后如何避免 JSON 键名不一致导致页面留白
翻译人员改 en.json 时新增了一个键 "footer.copyright",但忘了同步加到 zh.json 和 ja.json 里——自动化构建时,zh/index.html 里对应位置就变成空字符串,用户看到空白段落。
这不是前端代码问题,而是语言包治理缺失。自动化部署必须把“键名一致性”作为构建门禁。
- CI 脚本第一步:读取所有
locales/*.json,提取全部键名,生成集合 A(en)、B(zh)、C(ja) - 对比 A∩B∩C 是否等于 A,如果不是,报错并列出缺失键:
footer.copyright missing in zh.json and ja.json - 允许临时占位,但要求值为
""或"[TRANSLATE]",不能直接删键;否则构建失败 - 语言包提交 PR 时,用 GitHub Action 触发该检查,不通过则禁止合并——把问题卡在源头
- 生产环境不要 fallback 到
en填充缺失键,那会让用户误以为已翻译完成;留白反而能暴露问题
hreflang 或键名不齐,CI 就该失败,而不是静默上线。



















