2026年9月12日

2026年9月12日

WordPressのページネーションが動作しない問題を解決する方法

はじめに

WordPressのブログ一覧や検索結果ページで「次のページ」をクリックすると404エラーが表示される・URLが/page/2/に変わっても1ページ目と同じ内容が表示される・the_posts_pagination()を使っているのにページネーションが表示されない・WP_Queryでカスタムクエリを作成したがページネーションが機能しないといった問題は、パーマリンク設定・pagedパラメーターの設定ミス・$wp_queryの上書き・max_num_pagesの未設定が原因です。

症状・原因

  • パーマリンク設定が「基本」になっていて/page/2/形式のURLが機能しない
  • カスタムWP_Queryでpagedパラメーターを正しく渡していない
  • query_posts()を使用してメインクエリを上書きしているためmax_num_pagesが壊れている
  • 固定ページをフロントページに設定している場合のpagedとpageの混同

解決手順

ステップ1:ページネーションの問題を診断する

# ページネーション設定を確認
wp eval "
global \$wp_query;
echo 'posts_per_page: '  . get_option('posts_per_page') . PHP_EOL;
echo 'found_posts: '     . \$wp_query->found_posts . PHP_EOL;
echo 'max_num_pages: '   . \$wp_query->max_num_pages . PHP_EOL;
echo 'current paged: '   . get_query_var('paged') . PHP_EOL;
echo 'current page: '    . get_query_var('page') . PHP_EOL;
echo 'is_front_page: '   . (is_front_page() ? 'true' : 'false') . PHP_EOL;
echo 'permalink_structure: ' . get_option('permalink_structure') . PHP_EOL;
"

# rewriteルールにpagedが含まれているか確認
wp eval "
\$rules = get_option('rewrite_rules');
\$paged_rules = array_filter(array_keys(\$rules), fn(\$k) => str_contains(\$k, 'paged'));
echo 'Paged rewrite rules: ' . count(\$paged_rules) . PHP_EOL;
foreach (array_slice(\$paged_rules, 0, 3) as \$rule) {
    echo '  ' . \$rule . PHP_EOL;
}
"

ステップ2:パーマリンクとrewriteルールを修正する

# パーマリンクをリセット(最初に試すこと)
wp rewrite flush --hard

# フロントページが固定ページの場合の設定確認
wp eval "
echo 'show_on_front: '  . get_option('show_on_front') . PHP_EOL;
echo 'page_on_front: '  . get_option('page_on_front') . PHP_EOL;
echo 'page_for_posts: ' . get_option('page_for_posts') . PHP_EOL;
"
// テンプレートファイル: メインクエリのページネーション(正しい使い方)

// ✅ 正しい: the_posts_pagination() を使用
the_posts_pagination([
    'mid_size'  => 2,
    'prev_text' => '« 前のページ',
    'next_text' => '次のページ »',
]);

// ✅ 正しい: previous_posts_link / next_posts_link
previous_posts_link('« 前のページ');
next_posts_link('次のページ »', $wp_query->max_num_pages);

// ❌ 間違い: query_posts() はメインクエリを壊す
// query_posts('posts_per_page=5');  // 使用禁止

// ✅ 正しい: pre_get_posts フックでメインクエリを変更
add_action('pre_get_posts', function(WP_Query $query): void {
    if (!is_admin() && $query->is_main_query() && $query->is_home()) {
        $query->set('posts_per_page', 5);
    }
});

ステップ3:カスタムWP_Queryのページネーションを修正する

// テンプレートファイル: カスタムWP_Queryでのページネーション

// ✅ 正しい: pagedパラメーターを正しく渡す
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;

// フロントページの場合はpageを使用
if (is_front_page()) {
    $paged = (get_query_var('page')) ? get_query_var('page') : 1;
}

$custom_query = new WP_Query([
    'post_type'      => 'post',
    'posts_per_page' => 5,
    'paged'          => $paged,   // 必須:現在のページ番号
    'post_status'    => 'publish',
]);

if ($custom_query->have_posts()) :
    while ($custom_query->have_posts()) :
        $custom_query->the_post();
        // 投稿を表示
    endwhile;

    // ページネーションを表示($custom_queryのmax_num_pagesを渡す)
    the_posts_pagination([
        'total'     => $custom_query->max_num_pages,  // 必須
        'mid_size'  => 2,
        'prev_text' => '«',
        'next_text' => '»',
    ]);
endif;
wp_reset_postdata();
// functions.php: paginate_links() でカスタムページネーションを実装
function custom_pagination(int $max_num_pages, int $current_page): string {
    if ($max_num_pages <= 1) {
        return '';
    }

    $links = paginate_links([
        'base'      => str_replace(PHP_INT_MAX, '%#%', esc_url(get_pagenum_link(PHP_INT_MAX))),
        'format'    => '?paged=%#%',
        'current'   => max(1, $current_page),
        'total'     => $max_num_pages,
        'type'      => 'array',
        'prev_text' => '«',
        'next_text' => '»',
    ]);

    if (!$links) {
        return '';
    }

    return '<nav class="pagination"><ul>'
        . implode('', array_map(fn($link) => "<li>{$link}</li>", $links))
        . '</ul></nav>';
}

ステップ4:固定フロントページのページネーションを修正する

// functions.php: 固定フロントページでのページネーション対応
// 通常は paged ではなく page クエリ変数を使う

// フロントページに投稿一覧をページネーション付きで表示する場合
add_action('pre_get_posts', function(WP_Query $query): void {
    if ($query->is_main_query() && is_front_page() && !is_admin()) {
        $query->set('posts_per_page', 10);
        // フロントページでは paged ではなく page を使う
        $paged = get_query_var('page') ?: 1;
        $query->set('paged', $paged);
    }
});
# .htaccess: ページネーションのURLルールが壊れている場合
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /

# 重要: WordPress標準のルール(ページネーションが含まれる)
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

ステップ5:AJAXページネーションを実装する

// functions.php: AJAXで非同期ページネーション
add_action('wp_enqueue_scripts', function(): void {
    wp_enqueue_script(
        'ajax-pagination',
        get_template_directory_uri() . '/js/ajax-pagination.js',
        ['jquery'],
        '1.0',
        true
    );
    wp_localize_script('ajax-pagination', 'ajaxPagination', [
        'ajaxurl' => admin_url('admin-ajax.php'),
        'nonce'   => wp_create_nonce('ajax_pagination'),
    ]);
});

add_action('wp_ajax_load_more_posts',        'handle_load_more_posts');
add_action('wp_ajax_nopriv_load_more_posts', 'handle_load_more_posts');

function handle_load_more_posts(): void {
    check_ajax_referer('ajax_pagination', 'nonce');

    $page  = (int) ($_POST['page'] ?? 1);
    $query = new WP_Query([
        'post_type'      => 'post',
        'posts_per_page' => 5,
        'paged'          => $page,
        'post_status'    => 'publish',
    ]);

    ob_start();
    while ($query->have_posts()) {
        $query->the_post();
        get_template_part('template-parts/content');
    }
    $html = ob_get_clean();
    wp_reset_postdata();

    wp_send_json_success([
        'html'          => $html,
        'max_num_pages' => $query->max_num_pages,
    ]);
}

注意事項

  • query_posts()は絶対に使用しないでください。メインクエリを上書きしてページネーションを破壊します。代わりにpre_get_postsフックまたはWP_Queryを使用してください
  • カスタムWP_Queryでthe_posts_pagination()を使う場合は必ず'total' => $custom_query->max_num_pagesを渡してください。これを省略するとメインクエリのページ数が使用されます
  • 固定ページをフロントページに設定している場合、ページネーションにはpagedではなくpageクエリ変数が使用されます。get_query_var('page')を使うか、両方を確認してください

まとめ

WordPressページネーション不動作の解決は①$wp_query->max_num_pages・found_posts・get_query_var('paged')を確認・permalink_structureの設定確認・pagedのrewriteルール確認、②wp rewrite flush --hardでルールをリセット・query_posts()をpre_get_postsフックに置き換え・the_posts_pagination()を正しく使用、③カスタムWP_Queryにpagedパラメーターを渡す・the_posts_pagination(['total' => $query->max_num_pages])でページ数を明示・wp_reset_postdata()でクエリをリセット、④固定フロントページはget_query_var('page')を使用・pre_get_postsでフロントページのページ数を設定、⑤AJAXページネーションでwp_ajax_フックを実装・wp_create_nonceでセキュリティトークンを付与・wp_send_json_successでHTML片を返却の手順で解決します。

お気軽にご相談ください

お見積りへ お問い合わせへ
▲