lang属性必须在首屏HTML中写对,JS修改document.documentElement.lang对屏幕阅读器、Chrome翻译和SEO基本无效,因其仅在HTML解析初期被读取。

lang 属性不能“修改”——它必须在首屏 HTML 字符串中就写对。后续用 JavaScript 改 document.documentElement.lang,对屏幕阅读器、Chrome 翻译按钮、SEO 都基本无效。
为什么 JS 设置 lang 会失效
浏览器和辅助技术(如 NVDA、VoiceOver)只在解析 HTML 的最初阶段读取 <html lang="zh-CN">。DOM 构建完成后,再执行 document.documentElement.lang = "en-US",只是改了个属性值,没人重触发语音引擎加载、翻译入口激活或搜索引擎重索引。
- 现象:页面语言切换后,VoiceOver 仍用中文引擎读英文段落
- 现象:Chrome 地址栏不出现翻译按钮,或点了直接乱翻成日语
- 现象:Google Search Console 持续报“未指定语言”,哪怕控制台里能看到
lang值已变
静态/服务端渲染站点怎么设对 lang
核心原则:让真实语言值出现在 HTTP 响应的第一个字节里。
- 纯静态站(Hugo/Jekyll):每个语言版本生成独立 HTML 文件,模板中硬编码
<html lang="zh-CN">或<html lang="en-GB"> - SSR 框架(Next.js/Nuxt):在根布局层注入,例如 Next.js 的
app/layout.tsx中写<html lang={locale}>,locale来自路由参数或请求头 - PHP/Node 模板:服务端根据
Accept-Language或用户登录态拼接<html lang="= htmlspecialchars($lang, ENT_QUOTES) ?>">,务必防 XSS
单页应用(SPA)切换语言时的现实做法
如果你坚持纯前端多语言,且无法 SSR/SSG,只有两个勉强可行的路径:
- 整页刷新:
window.location.href = "/en/about",靠服务端返回带正确lang的新 HTML - 重写 outerHTML(慎用):
document.documentElement.outerHTML = document.documentElement.outerHTML.replace(/lang="[^"]*"/, 'lang="en-US"');但 ARIA 缓存不清、部分读屏器不响应,iOS VoiceOver 尤其不可靠
注意:即使走 JS 路径,也必须同步更新所有已有 lang 的子元素(如 <p lang="en">),否则局部多语言内容会错乱。
立即学习“前端免费学习笔记(深入)”;
lang 值写错比不写还糟
非法值不会报错,但会被静默忽略或识别为“未知语言”,导致更隐蔽的问题:
-
lang="zh_CN"(下划线)→ Chrome 当作无效,fallback 到系统默认 -
lang="Chinese"→ IANA 不收录,NVDA 直接跳过中文 TTS 引擎 -
lang=""→ 明确声明“语言未知”,中文页面可能被按英文规则切音节,“行”读成 háng 而非 xíng - 正确写法只有一种风格:小写字母 + 短横线,如
zh-CN、en-US、fr-FR
最容易被忽略的是:这些故障全无视觉提示。页面看起来完全正常,但可访问性、SEO、翻译功能已在后台断裂。



















