2026年5月20日
2026年5月20日
WordPressのページネーションのSEO設定方法
はじめに
WordPressのアーカイブページや長い記事のページネーションは、SEO上の設定を誤ると評価が分散したり、重複コンテンツとみなされたりします。Googleが2011年に導入したrel="prev/next"は2019年に廃止されましたが、その後の正しい対応方法を理解することが重要です。
症状・原因
- ページネーションのページ2以降がインデックスされすぎている(または全くされない)
/page/2/などのURLがカノニカル問題を起こしている- 無限スクロールを実装したがGoogleにコンテンツが認識されていない
- ページネーションページの直帰率が高くパフォーマンスが悪い
解決手順
ステップ1:ページネーションのSEO現状を確認する
# ページネーションURLのインデックス状況を確認
# Googleで: site:example.com/page/
# ページネーションのカノニカルを確認
curl -s https://example.com/page/2/ | grep -i canonical
# robots.txt でページネーションがブロックされていないか
curl -s https://example.com/robots.txt | grep -i page
# WordPressのページネーション設定を確認
wp option get posts_per_page # 1ページの投稿数
wp option get page_on_front # フロントページ設定
wp option get page_for_posts # 投稿一覧ページ
ステップ2:ページネーションのカノニカルURLを正しく設定する
// functions.php: ページネーションのカノニカルURL設定
// WordPress はデフォルトで各ページのカノニカルを自動設定する
// wp_head() を呼んでいれば基本的に正しく設定されている
// カノニカルの出力を確認(remove_action でプラグインの干渉を確認)
add_action('wp_head', function(): void {
if (is_paged()) {
// ページネーション時のカノニカルを手動で出力する場合
$page = get_query_var('paged') ?: 1;
$base = get_pagenum_link(1);
$current = get_pagenum_link($page);
// ページ1はベースURLをカノニカルに
$canonical = ($page === 1) ? $base : $current;
// ※ Yoast SEO などプラグインが出力する場合は重複するため削除する
}
}, 1);
// Yoast SEO のカノニカル出力をカスタマイズ
add_filter('wpseo_canonical', function(string $canonical): string {
if (is_paged()) {
// ページネーションページはそのままのURLをカノニカルに(デフォルト動作)
// page/1/ を / にリダイレクトする場合は自動的に処理される
}
return $canonical;
});
ステップ3:ページネーションページのnoindex設定を判断する
// functions.php: ページネーションのnoindex設定
// ※ SEO的にはページネーションをインデックスするのが基本
// 独自コンテンツのないページ2以降は状況次第
add_action('wp_head', function(): void {
// アーカイブのページ2以降をnoindexにする場合
// (コンテンツが薄い・独自性がない場合のみ推奨)
if (is_paged() && (is_category() || is_tag() || is_archive())) {
$page = get_query_var('paged');
if ($page > 1) {
// Yoast SEO を使っていない場合のみ出力
if (!defined('WPSEO_VERSION')) {
echo '<meta name="robots" content="noindex, follow">' . PHP_EOL;
}
}
}
// 記事内ページネーション(<!--nextpage-->)は基本インデックスOK
// → 各ページに固有コンテンツがあるため
}, 1);
// Yoast SEO での設定:
// SEO → 検索の見え方 → アーカイブ → ページネーション → ページ設定
// 「最初のページ以外はインデックスしない」 をONにする方法もある
ステップ4:rel=”prev/next”の代替対応を実装する
// Googleは2019年に rel="prev/next" のサポートを廃止
// 代わりに:
// 1. 正しいカノニカルURL(各ページ固有のURL)
// 2. ページネーション付きのHTMLリンク
// 3. サイトマップへの全ページ記載
// functions.php: ページネーションリンクをSEOフレンドリーに
// WordPress デフォルトのページネーション出力を改善
add_filter('wp_link_pages_args', function(array $args): array {
$args['before'] = '<nav class="page-links" aria-label="記事ページナビゲーション">';
$args['after'] = '</nav>';
$args['link_before'] = '<span>';
$args['link_after'] = '</span>';
return $args;
});
// アーカイブページのページネーション
// the_posts_pagination() の出力をカスタマイズ
add_filter('navigation_markup_template', function(string $template): string {
// aria-label を追加してアクセシビリティ改善
return str_replace(
'class="navigation',
'aria-label="ページナビゲーション" class="navigation',
$template
);
});
// サイトマップにページネーションを含める場合
add_filter('wp_sitemaps_posts_query_args', function(array $args): array {
// ページネーションページはサイトマップには含めない(通常)
return $args;
});
ステップ5:無限スクロールのSEO対応
// 無限スクロール実装時のSEO対応
// History API でURLを更新することでGoogleに各ページを認識させる
class InfiniteScroll {
constructor() {
this.page = 1;
this.loading = false;
this.maxPage = parseInt(document.body.dataset.maxPage || '1');
this.observer = new IntersectionObserver(this.onIntersect.bind(this));
const sentinel = document.querySelector('.load-more-sentinel');
if (sentinel) this.observer.observe(sentinel);
}
async onIntersect(entries) {
if (!entries[0].isIntersecting || this.loading) return;
if (this.page >= this.maxPage) return;
this.loading = true;
this.page++;
try {
const url = `${window.location.pathname}page/${this.page}/`;
const res = await fetch(url);
const html = await res.text();
// 新しいコンテンツを挿入
const parser = new DOMParser();
const doc = parser.parseFromString(html, 'text/html');
const posts = doc.querySelectorAll('.post');
const container = document.querySelector('.posts-container');
posts.forEach(post => container.appendChild(post));
// URLをHistoryAPIで更新(SEO・UX両立)
history.pushState({ page: this.page }, '', url);
} finally {
this.loading = false;
}
}
}
new InfiniteScroll();
// functions.php: 最大ページ数をbodyに出力(JS用)
add_filter('body_class', function(array $classes): array {
return $classes;
});
add_action('wp_head', function(): void {
global $wp_query;
$max_pages = $wp_query->max_num_pages ?? 1;
echo '<script>document.body.dataset.maxPage = ' . (int)$max_pages . ';</script>' . PHP_EOL;
});
注意事項
rel="prev/next"は2019年にGoogleがサポートを廃止しました。出力しても無害ですが、SEO効果はありません- ページネーションを全てnoindexにすると、後半ページの記事がインデックスされなくなります。コンテンツへの導線として一部のページはインデックスさせておくことを推奨します
- 無限スクロールはJavaScript無効環境やGooglebotが正しくレンダリングできない場合があります。
タグでHTMLページネーションへのフォールバックを提供してください
まとめ
ページネーションのSEO対応は①wp_head()が出力するカノニカルURLが各ページ固有のURLになっていることを確認、②コンテンツが薄いアーカイブの2ページ目以降は任意でnoindex設定、③rel="prev/next"は廃止済みのため不要、④無限スクロールはHistory APIでURLを更新してGoogleに各ページを認識させる、⑤サイトマップにはページネーションページを含めない、の順で設定します。