先把当时的情况摆出来。英文版靠 ?lang=en 参数切换,canonical 输出当前地址时把参数丢了,结果所有英文页的规范地址都指回中文原页,英文版零收录。

这类报错背后常见的原因有几处,逐个排除就行。canonical 生成时丢掉了查询参数。也可能是参数版被判为中文页的重复内容。

还有一种情况,hreflang 指向参数地址,与 canonical 互相矛盾。另外,sitemap 里没有带参数的地址,英文页缺少发现路径。

先看英文页的 canonical

curl -s 'https://www.example.com/post/1?lang=en' | grep -o '<link rel="canonical"[^>]*>'

然后改成独立目录

rewrite ^/en/post/([0-9]+)/?$ /post/$1?lang=en last;

canonical 指向新目录地址

add_filter('get_canonical_url', function($u){ return is_lang_en() ? str_replace('/post/','/en/post/',$u) : $u; });

提交更新后的索引文件

curl -s https://www.example.com/sitemap-en.xml | grep -c '<loc>'

改之前我把相关日志按时间截了一段存着,事后对时间线用得上。

中途换过一次思路,把范围缩到最小的那一层,反而快了。

恢复的判定其实很直接。英文页 canonical 指向 /en/ 目录自身,与 hreflang 一致,四周内英文页开始出现在索引里。

参数式多语言最大的问题是 canonical 容易写丢,改成子目录能省掉一整类冲突。如果同一现象隔几天又出现,说明根因没找到,别当偶发处理。

作者 9823189