最稳的多语言静态站点方案是采用顶层语言子目录结构(如/、/en/、/zh/),每个子目录下部署完整且精准翻译的HTML页面,并通过服务端动态注入正确的lang属性、手动写死hreflang标签与绝对路径语言切换链接,以确保SEO友好、无障碍访问及用户体验一致。

目录结构必须按语言子目录隔离
静态站点要真正支持多语言且 SEO 友好,不能把所有语言塞进一个 HTML 文件里,也不能靠 JS 切换就完事。最稳的路径是顶层语言子目录:/、/en/、/zh/、/ja/ 这样的结构。
每个子目录下放完整的一套页面(index.html、about.html 等),内容为该语言的手动精准译文。这样 Google 能明确识别 hreflang 关系,用户点击「中文」按钮直接跳转到 /zh/about.html,而不是刷新当前页再替换文字——避免表单丢失、滚动跳动、状态重置。
-
/作为默认语言(比如英文)根目录,不加前缀 -
/zh/下所有链接必须以/zh/开头,例如<a href="/zh/contact.html">,不能写contact.html或../contact.html - 新增语言只需新建目录、复制结构、填入译文,无需改任何逻辑
- 构建工具(如 Eleventy、Hugo)可自动从模板生成各语言目录;纯手写也只需维护一套 HTML 结构 + 多套文案
HTML 根节点 lang 属性必须动态匹配当前语言路径
用户访问 /zh/about.html,<html lang="zh-CN"> 就得真实存在,不能靠 JS 启动后再改——否则首屏渲染时屏幕阅读器读错音、浏览器翻译提示失效、CSS 的 ::lang(zh) 伪类不生效。
这个值不能硬编码在模板里,也不能只靠 navigator.language 推断。正确做法是服务端根据请求路径(或 Accept-Language)注入:
立即学习“前端免费学习笔记(深入)”;
- Node.js:解析
req.url,提取路径前缀/zh/→ 设res.locals.lang = 'zh-CN' - PHP:用
$_SERVER['REQUEST_URI']截取语言码,映射为 BCP 47 标准(zh→zh-CN,en→en-US) - 静态托管(Vercel/Netlify):用 _redirects 或 middleware 提取路径并注入
<html lang="{{lang}}">
漏掉这步,lang 就只是个摆设——它影响拼写检查、字体回退、标点间距,不是“看起来像”就行。
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
data-i18n 标记只用于动态文本,不替代语言子目录
如果你已经用了 /zh/、/en/ 这种结构,data-i18n 就不该出现在主页面文本上。它的合理位置是:页脚实时更新的版权声明、用户登录后的欢迎语、AJAX 加载的评论列表——这些内容无法提前写死在静态 HTML 中。
强行给整个页面打 data-i18n 再配 JSON 包,等于放弃静态优势:首屏白屏时间变长、SEO 爬虫看到的是占位符、离线缓存失效、翻译键名容易漏或冲突。
- 表单 placeholder、
title、alt必须用data-i18n-placeholder等带后缀属性,data-i18n默认只改textContent - 含 HTML 的文案(如“请阅读服务条款”)需用
innerHTML替换,但语言包对应值必须是已过滤 XSS 的纯 HTML 片段 - 不要给
<script>或<pre>加data-i18n——它们不渲染为可见文本,加了无效
hreflang 标签和语言切换栏必须每页手动写死
Google 靠 <link rel="alternate" hreflang="zh" href="/zh/"> 理解语言关系,它不会自动推断。你得在每页 <head> 里显式声明所有语言版本的 URL。
语言切换栏(如「English | 中文 | 日本語」)也不能靠 JS 渲染,必须写在 HTML 源码里。否则爬虫看不到,SPA 路由未激活时点击会 404。
- 每个语言版本的页面,都要包含指向其他所有语言版本的
hreflang标签 - 切换链接必须用绝对路径:
<a href="/en/about.html">English</a>,不能用相对路径或 JSlocation.href - 如果用构建工具,可用数据文件(如 languages.json)生成这些标签和导航,但最终输出仍是静态 HTML
最容易被忽略的是:语言切换栏里的链接,必须和当前页面路径层级一致。在 /zh/products/widget.html 里,「English」应指向 /en/products/widget.html,而不是 /en/ ——否则用户会丢失上下文。


















