Пагинация в WordPress: номера страниц и ошибка 404
← Блог
WordPress · 03.10.2026 · 4 мин чтения

Пагинация в WordPress: номера страниц и ошибка 404

Пагинация в WordPress делит список записей на страницы и выводит ссылки с номерами. Для стандартного блога и архивов достаточно the_posts_pagination(). Для отдельного WP_Query используют paginate_links().

Разберём оба варианта и причины, по которым вторая страница возвращает 404 или повторяет первую.

1. Номера страниц в основном цикле WordPress

В index.php, home.php или archive.php после цикла:

<?php
the_posts_pagination( array(
    'mid_size'           => 1,
    'prev_text'          => 'Назад',
    'next_text'          => 'Вперёд',
    'screen_reader_text' => 'Навигация по страницам',
    'aria_label'         => 'Страницы записей',
) );
?>

Функция выводит <nav class="navigation pagination"> с номерами страниц. Текущая страница получает aria-current="page", а mid_size задаёт, сколько номеров показывать по бокам от текущей. Если страница всего одна, ничего не выводится.

Число записей на странице берётся из «Настройки → Чтение → На страницах блога отображать не более». Для простых ссылок «Новее / Старее» без номеров есть the_posts_navigation().

2. Число записей на странице через pre_get_posts

Не заменяй основной цикл архива своим WP_Query только ради другого количества записей. WordPress определяет существование страницы ещё до загрузки шаблона.

Если основной запрос насчитал две страницы, а твой — три, адрес /page/3/ может вернуть 404. Число записей в основном запросе меняй через pre_get_posts.

Правильный способ — изменить основной запрос до его выполнения:

function mytheme_archive_query( $query ) {
    if ( is_admin() || ! $query->is_main_query() ) {
        return;
    }

    if ( $query->is_category() ) {
        $query->set( 'posts_per_page', 12 );
    }

    if ( $query->is_home() ) {
        $query->set( 'ignore_sticky_posts', true );
    }
}
add_action( 'pre_get_posts', 'mytheme_archive_query' );

Проверка is_main_query() ограничивает изменение основным запросом. Условие ! is_admin() исключает административные экраны. В шаблоне остаются обычный цикл и the_posts_pagination().

3. Пагинация отдельного WP_Query

Отдельный запрос нужен для дополнительного списка в шаблоне страницы — например, новостей на странице услуг. Передай ему текущий номер страницы, а общее число страниц возьми из результата этого же запроса:

<?php
$paged = max( 1, get_query_var( 'paged' ), get_query_var( 'page' ) );

$news = new WP_Query( array(
    'post_type'      => 'post',
    'category_name'  => 'news',
    'posts_per_page' => 6,
    'paged'          => $paged,
) );

if ( $news->have_posts() ) :
    while ( $news->have_posts() ) :
        $news->the_post();
        get_template_part( 'template-parts/card' );
    endwhile;

    $links = paginate_links( array(
        'total'     => $news->max_num_pages,
        'current'   => $paged,
        'mid_size'  => 1,
        'prev_text' => 'Назад',
        'next_text' => 'Вперёд',
    ) );

    if ( $links ) {
        echo '<nav class="pagination" aria-label="Страницы новостей"><div class="nav-links">' . $links . '</div></nav>';
    }

    wp_reset_postdata();
endif;
?>
  • На обычных страницах номер приходит в paged, а на статической главной — в page. max() учитывает оба случая.
  • total берётся из твоего запроса, а не из глобального $wp_query — иначе ссылок будет не столько, сколько нужно.
  • paginate_links() сама строит адреса вида /news/page/2/ на основе текущей ссылки.
  • wp_reset_postdata() возвращает глобальную запись страницы после своего цикла.

CSS для номеров страниц

.pagination .nav-links {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.pagination .page-numbers {
  display: inline-grid;
  place-items: center;
  min-width: 44px;
  min-height: 44px;
  padding: 0 12px;
  border: 1px solid #d1d5db;
  border-radius: 8px;
  text-decoration: none;
}

.pagination .page-numbers.current {
  background: #1f2937;
  border-color: #1f2937;
  color: #fff;
}

.pagination .page-numbers.dots {
  border-color: transparent;
}

Обёртка .nav-links одинакова у the_posts_pagination() и у своего вывода, поэтому стили общие. Номера по 44 пикселя удобно нажимать пальцем. Многоточие получает класс dots и не является ссылкой.

Почему пагинация не работает: 404 и повторы

  • Свой запрос заменяет основной в архиве — перенеси изменения в pre_get_posts.
  • Ярлык страницы совпадает с ярлыком рубрики или типа записей, например страница news и рубрика news с отключённым префиксом. Переименуй одно из них.
  • Вторая страница повторяет первую — в запрос не передан paged.
  • После изменений в типах записей или структуре ссылок открой «Настройки → Постоянные ссылки» и нажми «Сохранить», чтобы обновить правила.

Если записи выводятся на отдельной странице блога, сначала проверь её настройку — об этом статья о блоге на отдельной странице.

Документация

Есть вопрос или дополнение?

Обсудить в Telegram

Добавить комментарий