lang属性写错会导致hreflang被google静默忽略;必须确保与语言代码完全一致(大小写、连字符、无空格),否则整组hreflang失效,且不报错。

lang属性写错导致hreflang被Google静默忽略
Google明确要求:和<link rel="alternate" hreflang="zh-CN" href="...">中的语言代码必须完全一致——大小写、分隔符、子标签全部匹配。一个写zh-cn,另一个写zh-CN,整组hreflang会被当成自相矛盾而直接丢弃,不报错、不警告,只静默失效。
常见错误包括:zh_CN(下划线)、Chinese(非标准)、zh-ch(子标签非法)、cn(不是语言码)。这些值浏览器不报错,但搜索引擎和屏幕阅读器全当没写。
验证方法:用 Google Search Console 的「URL 检查」工具抓取页面,在「国际化」标签页看是否列出有效hreflang对应关系。没列出来,八成是lang或hreflang值不规范。
局部多语言内容没加lang,屏幕阅读器直接读错
根只定义主语言,对内嵌的英文术语、日文引用、<code>块里的命令完全无效。不显式标注,NVDA、VoiceOver 就会用中文引擎硬读npm run build,发音生硬甚至无法识别。
必须为所有非主语言内容加lang属性:
<blockquote lang="fr">Je suis français.</blockquote>-
<p>调用 <code lang="bash">curl -X POST(lang="bash"虽非BCP 47标准,但被主流语法高亮工具识别) <figcaption lang="ja">図1:システム構成</figcaption>
别依赖父级继承::lang(zh) CSS选择器能继承,但屏幕阅读器、浏览器翻译、拼写检查器只认显式声明的lang值。
SPA切换语言后只改document.documentElement.lang,子元素lang全失效
React/Vue里切语言时,只执行document.documentElement.lang = "en-US"远远不够。已渲染的<p lang="zh-CN"></p>、<pre class="brush:php;toolbar:false;" lang="bash"></pre>等节点仍保留旧值,屏幕阅读器继续按旧语言朗读,CSS :lang()也不匹配。
正确做法是手动遍历更新:
- 切换前,先收集所有带
lang属性的元素:document.querySelectorAll('[lang]') - 遍历并重设:
el.setAttribute('lang', newLang),注意newLang必须是标准化BCP 47格式(如en-US,不能是EN-us) - 服务端渲染(SSR)场景更关键:初始HTML中
必须真实存在,JS注入属于“补救”,AT兼容性已受损
最麻烦的不是写错,而是写了但没测——不同屏幕阅读器对嵌套lang的解析深度不一致,NVDA可能正常,VoiceOver却跳过某段。
lang="zh"这类宽泛值在可访问性上实际不可用
lang="zh"语法合法,但不符合 IETF BCP 47 实际要求。屏幕阅读器无法据此选择合适的语音引擎,结果是分词错误、声调错乱、标点停顿异常。iOS VoiceOver某些版本甚至会降级为英语发音。
必须用具体区域变体:
- 简体中文大陆用户 →
zh-CN或zh-Hans - 繁体中文台湾用户 →
zh-TW或zh-Hant - 繁体中文香港用户 →
zh-HK
验证方式:浏览器控制台运行Intl.getCanonicalLocales("zh-CN"),返回["zh-CN"]才算合规;返回["und"]说明输入值被浏览器视为未知。
真正难的不是记住zh-CN怎么写,而是让每个<title></title>、<placeholder></placeholder>、<svg title></svg>、JS动态插入的弹窗文案,都带着准确且可验证的lang——这些地方最容易漏。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











