必须唯一、闭合、置于 中且为绝对url,动态插入或放于无效;参数需按语义过滤,干扰型剔除、语义型保留;与noindex、301混用会冲突。

直接写对 <link rel="canonical"> 就能解决大部分重复内容索引冲突,但写错比不写更危险——它不是开关,是给搜索引擎的明确建议,信号一错,内页权重可能被清零。
canonical 标签必须放在 里,且只能有一个
搜索引擎只解析 HTML 初始源码的 区域,不会执行 JS,也不看 里的内容。你用 document.head.appendChild() 动态插入,或者把标签塞进 开头,Google 就当它不存在。
- 检查最终 HTML 源码(右键 → “查看网页源代码”),搜索
rel="canonical",确认它唯一、闭合、且在内 - CMS 或多插件主题容易重复注入——比如 SEO 插件 + 主题模板各写一个,结果页面出现两个
<link rel="canonical">,Google 可能直接忽略整条 - Next.js 中避免在
getStaticProps里硬编码路径;Nuxt 3 别用route.fullPath(含 query),改用route.path构造
href 值必须是绝对 URL,协议/域名/路径缺一不可
相对路径如 /article/123 或协议相对路径如 //example.com/article 都会因上下文不同被解析成错误地址:HTTP 页面里变成 http://,HTTPS 页面里变成 https://,CDN 回源时还可能指向错误源站。
- 正确写法只有这一种:
<link rel="canonical" href="https://www.example.com/article/123"> -
https://不能省,www.和非www.是两个不同规范域,选一个并全站统一 - 路径末尾斜杠必须和目标页面真实返回的 URL 一致:
/article/≠/article,否则返回 404 或跳转都会让 canonical 失效 - PHP 中推荐用
parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH)提取路径,再拼上$_SERVER['HTTP_HOST']
动态页面中怎么安全过滤参数?分页和追踪参数处理逻辑完全不同
核心判断标准:参数是否改变页面主体内容?干扰型参数(如 ?utm_source、?ref、?sort)要剔除;语义型参数(如 ?page=2、?q=foo)通常应保留——第 2 页不是第 1 页的副本,它有独立索引价值。
- 电商商品页访问
/product?id=123&utm_source=email,canonical 应指向/product/123(无参标准路径) - 博客列表页访问
/blog?page=2,canonical 必须指向自身https://example.com/blog?page=2,绝不能指向/blog,否则 Google 会认为该页无独立价值 - Next.js 中别直接用
router.asPath,应在自定义 hook 里手动剔除 tracking 类 query 参数 - AMP 页面的
<link rel="canonical">指向 PC 版,PC 版就必须有对应<link rel="amphtml">,双向缺一不可
canonical 不是重定向,和 noindex、301 混用会互相打架
它只是建议,不是强制指令。很多问题看似重复,其实该用别的手段——用错组合,反而触发惩罚。
- 已配置 301 跳转的旧 URL,不要再加 canonical 指回自己或跳转前地址
- 在
<meta name="robots" content="noindex">的页面上还加 canonical,属于逻辑矛盾,Google 很可能忽略该 canonical - 全站所有页面 canonical 都指向首页?这是最严重误用,等于主动放弃全部内页权重
- 目标 URL 必须返回 HTTP 200 状态码,不能是 301/302 跳转链中间页,也不能是 404 或 robots.txt 禁止抓取的地址
最容易被忽略的其实是“一致性”:服务端生成时用的 host 变量是否可信、静态生成器里 site.url 是否已同步更新、HTTPS 迁移后是否批量替换了所有 http://。这些细节不出现在控制台报错里,但会让 canonical 在爬虫眼里彻底失效。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











