中文商品页是 /zh/red-shirt.html,页面 canonical 却指向英文默认店铺。搜索引擎可能把当前页信号合并到另一个 URL。处理前先抓取真实 HTML,不要只看浏览器地址栏。

curl -sk https://shop.example.com/red-shirt.html -o /tmp/en.html
curl -sk https://shop.example.com/zh/red-shirt.html -o /tmp/zh.html
grep -ioE '<link[^>]+canonical[^>]*>' /tmp/en.html /tmp/zh.html

一:Base URL 和 Store Code

bin/magento store:list
bin/magento config:show web/url/use_store
bin/magento config:show web/secure/base_url
bin/magento config:show web/unsecure/base_url

同域名加 Store Code 与独立域名的生成方式不同。配置要在正确 scope 下检查,默认范围正确不代表中文 Store View 正确。

二:Magento 自带 canonical 开关

bin/magento config:show catalog/seo/product_canonical_tag
bin/magento config:show catalog/seo/category_canonical_tag
bin/magento config:show catalog/seo/product_use_categories

这些开关决定商品和分类是否输出 canonical,但不会自动解决 hreflang 和跨店铺策略。商品是否带分类路径也会产生不同 URL。

三:主题或 SEO 扩展是否覆盖 head

grep -RniE 'canonical|hreflang|rel=.alternate' app/design app/code | head -n 120
bin/magento module:status | grep -i seo

若主题直接拼默认 Base URL,任何 Store View 都会指回默认站。应使用当前 Store 的 URL 服务和目标 Store 重写,不能只做字符串替换。

制作一个矩阵:英文商品、中文商品、英文分类、中文分类各抓一次,记录 HTTP 状态、canonical 与 hreflang。canonical 应指当前语言的首选 URL,hreflang 才负责语言对应;中文页 canonical 到英文页,同时声明中文自引用,会产生冲突信号。

分页、筛选和协议也要进入抽查

分类第二页、带 layered navigation 参数的 URL 和 HTTP 到 HTTPS 跳转可能由不同模块处理。首选页应输出稳定 canonical,参数页不能互相形成跳转链。用同一抓取脚本保存响应码、最终 URL 和 canonical,便于上线前后比较。

curl -skIL 'https://shop.example.com/zh/category.html?p=2' | egrep -i 'HTTP/|location:'
curl -sk 'https://shop.example.com/zh/category.html?p=2' | grep -ioE '<link[^>]+canonical[^>]*>'