PAYATHON 2026

WordPress 分页的 canonical 链接为什么缺少 page/?

数据阿明

结论

这个现象可能是 WordPress 将请求当作单篇文章或独立 Page 的内容分页来处理,尤其要检查静态首页的分页。仅凭 URL 和模板文件名,无法确定具体原因。

get_site_url() 不会返回当前分页 URL。把它写进 canonical,通常只会让第 2 页的 canonical 指向 WordPress 安装地址,无法修复分页地址。

为什么会生成 /2/

WordPress 中有两种分页,需要区分:

  • 列表分页:例如文章列表的第 2 页,常见地址为 /page/2/,通常使用查询变量 paged。
  • 内容分页:例如通过 <!--nextpage--> 拆分一篇文章或一个 Page,通常使用查询变量 page,固定链接可能表现为 /article/2/。

静态首页的分页需要特别检查:页码可能通过 page 获取,不能仅因为地址中出现 page 就判断查询变量是 paged。参见 get_query_var() 文档。

核心的 wp_get_canonical_url() 从 get_permalink() 开始生成地址。当当前对象的 page >= 2 且启用了固定链接时,它会直接追加页码,在这一分支中不会插入 page/。因此,如果基础永久链接是 https://example.xy/,页码是 2,这一逻辑可以解释为什么得到 https://example.xy/2/。这只是根据核心逻辑作出的条件性解释,仍需核对站点实际的查询状态。参见 wp_get_canonical_url() 源码。

先确认页面类型和输出来源

建议按以下顺序排查:

  1. 在 WordPress 的“设置 → 阅读”中,确认该地址对应静态首页、文章列表页,还是其他页面。
  2. 检查请求中的 page、paged,以及 is_singular()、is_front_page()、is_home()、is_archive() 的结果。
  3. 查看页面源代码,确认 canonical 是否重复,并检查主题、SEO 插件及 get_canonical_url 过滤器是否修改了输出。
  4. 检查自定义分页查询和重写规则是否使用了正确的页码变量。

核心的 rel_canonical() 只为 is_singular() 成立的请求输出标签。如果实际请求是分类归档或文章列表,canonical 可能来自主题或插件;header-archivpage.php 这个文件名本身不能证明请求属于归档。参见 rel_canonical() 源码。

如何修正

如果查询或重写规则把列表分页错误地映射为内容分页,应先修正映射,让页面查询、分页导航和 canonical 使用一致的地址规则。如果 canonical 由 SEO 插件管理,应在该插件的配置或过滤接口中修正。

如果已经确认满足以下条件,可以通过核心过滤器做局部修正:

  • 问题发生在静态首页,首页模板展示自定义分页列表。
  • /page/2/ 等地址能够正常显示对应列表内容。
  • canonical 确实由核心 rel_canonical() 输出。
  • 页码已正确出现在 page 或 paged 中,且不是正文的 <!--nextpage--> 分页。

在这些前提下,可以将以下代码放入子主题的 functions.php 或站点功能插件:

add_filter( 'get_canonical_url', function ( $canonical_url, $post ) {
    if ( ! is_front_page() || ! is_page() ) {
        return $canonical_url;
    }

    if ( (int) $post->ID !== get_queried_object_id() ) {
        return $canonical_url;
    }

    $page_number = max(
        1,
        (int) get_query_var( 'page', 0 ),
        (int) get_query_var( 'paged', 0 )
    );

    if ( $page_number > 1 ) {
        return get_pagenum_link( $page_number, false );
    }

    return $canonical_url;
}, 10, 2 );

get_pagenum_link() 会依据固定链接设置和分页基础路径生成列表分页链接,避免直接硬编码 /page/。它也可能保留请求中的查询参数;如果站点存在跟踪、筛选或排序参数,需要另外明确这些参数的 canonical 策略。参见 get_pagenum_link() 文档。

使用这一方案时,需要恢复核心的 canonical 输出,并移除模板中手写的标签。示例只适用于上述静态首页场景,不能直接覆盖所有归档页和自定义页面。

为什么原来的临时处理不合适

<link rel="canonical" href="<?php echo get_site_url(); ?>">

get_site_url() 返回 WordPress 应用文件所在的地址,不包含当前请求的分页路径。WordPress 安装在子目录时,它还可能与网站对外首页地址不同。参见 get_site_url() 文档。

对于各页展示不同列表内容的分页序列,应让每页使用自己的 canonical URL,而不是统一指向第 1 页或站点根地址。这也符合 Google 的分页建议。

修正后,检查第 1、2、3 页的内容是否随页码变化、canonical 是否只有一个,以及目标地址是否正常返回且无需再次重定向。末尾斜杠应遵循站点的固定链接规则,不能单凭 /page/2 与 /page/2/ 的差异判断错误。

备注:内容仅供参考。