2026年6月3日
2026年6月3日
WordPressのページネーションをカスタマイズする方法・ページ番号・前後リンク設定
はじめに
「投稿一覧のページ送りをカスタマイズしたい」「カスタムクエリにページネーションが効かない」——WordPressのページネーションはpaginate_links()とWP_Queryのpagedパラメータを正しく組み合わせることで実装できます。
症状・原因
カスタムループでページネーションが動作しない主な原因は、pagedパラメータの取得方法の誤りです。フロントページではpage、アーカイブページではpagedを使う必要があります。またthe_posts_pagination()とpaginate_links()の使い方を理解することが重要です。
解決手順
ステップ1:標準のページネーションを表示する
// テーマのテンプレートでページネーションを表示
// メインクエリに対してはthe_posts_pagination()を使用
the_posts_pagination( [
'mid_size' => 2, // 現在ページ前後に表示するページ数
'prev_text' => '← 前のページ',
'next_text' => '次のページ →',
'screen_reader_text' => 'ページナビゲーション',
'type' => 'plain', // 'plain' | 'list' | 'array'
] );
// 前の投稿・次の投稿リンク(単一投稿ページ用)
the_post_navigation( [
'prev_text' => '<span>← 前の記事</span><span>%title</span>',
'next_text' => '<span>次の記事 →</span><span>%title</span>',
] );
ステップ2:paginate_links()でカスタムページネーションを作る
// paginate_links()でフルカスタム
function get_custom_pagination( $query = null ) {
global $wp_query;
$q = $query ?? $wp_query;
$total = $q->max_num_pages;
$current = max( 1, get_query_var( 'paged' ) );
if ( $total <= 1 ) return '';
$links = paginate_links( [
'base' => str_replace( 999999999, '%#%', esc_url( get_pagenum_link( 999999999 ) ) ),
'format' => '?paged=%#%',
'current' => $current,
'total' => $total,
'mid_size' => 2,
'end_size' => 1,
'prev_text' => '«',
'next_text' => '»',
'type' => 'array',
] );
if ( ! $links ) return '';
$output = '<nav class="pagination" aria-label="ページナビ"><ul>';
foreach ( $links as $link ) {
$output .= '<li>' . $link . '</li>';
}
$output .= '</ul></nav>';
return $output;
}
ステップ3:カスタムWP_Queryにページネーションを追加する
// カスタムクエリのページネーション(最も重要な実装)
$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' => 10,
'paged' => $paged, // ← これが必須
'category_name' => 'news',
] );
while ( $custom_query->have_posts() ) {
$custom_query->the_post();
// 表示処理
}
// ページネーションを表示(カスタムクエリを渡す)
echo get_custom_pagination( $custom_query );
wp_reset_postdata();
ステップ4:AjaxでLoad Moreボタンを実装する
// functions.phpにAjaxハンドラーを追加
add_action( 'wp_ajax_load_more_posts', 'handle_load_more' );
add_action( 'wp_ajax_nopriv_load_more_posts', 'handle_load_more' );
function handle_load_more() {
check_ajax_referer( 'load_more_nonce', 'nonce' );
$page = absint( $_POST['page'] ?? 1 );
$query = new WP_Query( [
'post_type' => 'post',
'posts_per_page' => 6,
'paged' => $page,
] );
if ( ! $query->have_posts() ) {
wp_send_json_error( 'no_posts' );
}
ob_start();
while ( $query->have_posts() ) {
$query->the_post();
get_template_part( 'template-parts/post-card' );
}
$html = ob_get_clean();
wp_reset_postdata();
wp_send_json_success( [
'html' => $html,
'has_more' => $page < $query->max_num_pages,
] );
}
// Load Moreボタンの処理
document.addEventListener('DOMContentLoaded', function() {
const btn = document.getElementById('load-more');
const container = document.getElementById('posts-container');
if (!btn) return;
let page = 2; // 初期表示が1ページ目なので2から開始
btn.addEventListener('click', async function() {
btn.textContent = '読み込み中…';
btn.disabled = true;
const form = new FormData();
form.append('action', 'load_more_posts');
form.append('nonce', wpData.nonce);
form.append('page', page);
const res = await fetch(wpData.ajaxUrl, { method: 'POST', body: form });
const data = await res.json();
if (data.success) {
container.insertAdjacentHTML('beforeend', data.data.html);
page++;
if (!data.data.has_more) btn.remove();
else { btn.textContent = 'もっと見る'; btn.disabled = false; }
}
});
});
ステップ5:投稿数の設定を変更する
// カスタムクエリの投稿数をページタイプ別に変更
add_action( 'pre_get_posts', function( $query ) {
if ( ! $query->is_main_query() || is_admin() ) return;
if ( $query->is_category() ) {
$query->set( 'posts_per_page', 12 ); // カテゴリーページは12件
}
if ( $query->is_search() ) {
$query->set( 'posts_per_page', 20 ); // 検索結果は20件
}
} );
注意事項
- カスタムWP_Queryで
pagedを設定しない場合、ページネーションのリンクは正しく表示されてもページ切り替えが機能しません。必ず'paged' => $pagedを含めてください。 - フロントページ(
is_front_page())ではget_query_var('paged')が0を返すことがあるため、get_query_var('page')も確認してください。 - Ajaxページネーションの場合、URLが変わらないため検索エンジンに全ページがインデックスされません。SEOが重要なサイトでは通常のページネーションを優先してください。
まとめ
ページネーションの実装は「the_posts_pagination()でメインクエリ→paginate_links()でカスタムデザイン→WP_QueryのpagedパラメータでカスタムLoop→Ajaxでロードモア」の流れで構築できます。フロントページとアーカイブページでpagedパラメータの取得方法が違う点に特に注意してください。関連記事:WordPressでカスタム投稿タイプを登録する方法、WordPressでAjaxを使った動的コンテンツを実装する方法。