Сценарий типичный: каталог товаров открывается нормально, но переход на /page/2/ или на следующую страницу архива заканчивается 404. Чаще всего это всплывает после смены структуры постоянных ссылок, включения кеша, правок в pre_get_posts или установки плагина фильтров. В WooCommerce проблема обычно не в самой пагинации, а в том, что запрос перестаёт совпадать с правилами перезаписи или с тем, что считает текущей страницей шаблон.
Если у вас уже есть рабочая пагинация на обычных записях, а ломается только магазин, значит смотреть нужно в сторону архива товаров, страницы магазина, кастомных запросов и кеша HTML. Ниже — практический разбор без лишней теории.
Как понять, что ломается именно пагинация, а не сам архив
Сначала важно отделить 404 на уровне WordPress от ошибки, которую отдаёт кеш или сервер. Откройте:
- главную страницу магазина;
- страницу
/shop/page/2/или эквивалентный URL; - страницу с фильтром и пагинацией, если она есть;
- тот же URL в режиме инкогнито и после очистки кеша.
Если первая страница каталога работает, а вторая — нет, обычно проблема в одном из трёх мест:
- не обновились правила перезаписи после изменения ЧПУ;
- кастомный запрос не передаёт корректный
paged; - кешируетcя HTML первой страницы и на второй подставляется не тот контент или не тот canonical.
Что проверить в админке и в коде
- Настройки → Постоянные ссылки: сохранены ли они после изменений.
- WooCommerce → Настройки → Товары: не менялся ли slug страницы магазина.
- Есть ли в теме или плагине фильтрации свой
WP_Queryдля каталога. - Не используется ли одновременно
pagedиpageв одном шаблоне.
Почему WooCommerce отдаёт 404 на страницах каталога
У WooCommerce архив товаров может строиться как обычный архив, как страница магазина или как результат модифицированного основного запроса. Если шаблон или плагин вмешивается в запрос, WordPress может считать, что запрошенной страницы не существует. Это особенно заметно, когда:
- в
pre_get_postsменяютposts_per_page, но забывают про пагинацию; - в шаблоне каталога создают отдельный
WP_Queryи выводят пагинацию от него без корректногоmax_num_pages; - кеш страницы хранит HTML первой страницы и отдаёт его на всех URL;
- плагин фильтров добавляет свои query vars, но rewrite rules не обновлены.
| Подход | Когда подходит | Риск |
|---|---|---|
| Исправить основной запрос | Каталог строится через архив WooCommerce | Нужно аккуратно тестировать фильтры и сортировку |
Использовать отдельный WP_Query | Нужен кастомный вывод товаров на отдельной странице | Легко сломать paged и max_num_pages |
| Сбросить правила перезаписи и кеш | Проблема появилась после правок ЧПУ | Не решает ошибки в шаблоне |
Пошаговое решение
1. Сбросьте правила перезаписи после изменения ссылок
Если вы меняли slug магазина, структуру записей или ставили плагин фильтров, сначала обновите правила. Самый безопасный способ — просто сохранить постоянные ссылки в админке. Это не «магия», а принудительная пересборка rewrite rules.
Если нужно сделать это программно после активации своего плагина, используйте только разовый сброс:
<?php
register_activation_hook(__FILE__, function () {
flush_rewrite_rules();
});
register_deactivation_hook(__FILE__, function () {
flush_rewrite_rules();
});Важно: не вызывайте flush_rewrite_rules() на каждом запросе. Это тяжёлая операция и для продакшена не подходит.
2. Проверьте, как формируется запрос товаров
Если вы меняете каталог через pre_get_posts, убедитесь, что не ломаете архив WooCommerce. Пример корректной правки основного запроса:
<?php
add_action('pre_get_posts', function (WP_Query $query) {
if (is_admin() || ! $query->is_main_query()) {
return;
}
if (function_exists('is_shop') && (is_shop() || is_product_taxonomy())) {
$query->set('posts_per_page', 24);
$query->set('orderby', 'date');
$query->set('order', 'DESC');
}
});Здесь мы не трогаем paged вручную, потому что основной запрос сам его понимает. Ошибка начинается, когда разработчик добавляет собственный paged поверх уже существующего.
3. Если используется отдельный WP_Query, передавайте paged правильно
На кастомных шаблонах каталога часто делают отдельный запрос товаров. Тогда пагинация должна брать текущую страницу из query vars и передавать её в запрос. Рабочий вариант выглядит так:
<?php
$paged = max(1, (int) get_query_var('paged'));
$args = array(
'post_type' => 'product',
'post_status' => 'publish',
'posts_per_page' => 12,
'paged' => $paged,
);
$products = new WP_Query($args);
if ($products->have_posts()) {
while ($products->have_posts()) {
$products->the_post();
wc_get_template_part('content', 'product');
}
echo paginate_links(array(
'total' => $products->max_num_pages,
'current' => $paged,
'type' => 'list',
));
wp_reset_postdata();
}Если вместо get_query_var('paged') использовать статичную единицу, вторая страница будет строиться неправильно. Если забыть wp_reset_postdata(), можно сломать следующий блок на странице.
4. Очистите кеш страницы и проверьте исключения
При HTML-кеше 404 иногда маскируется под «неработающую пагинацию». Особенно это заметно, если кешируется первая страница каталога, а URL второй страницы отдают тот же HTML. Проверьте:
- не кешируется ли
/shop/page/2/как/shop/; - есть ли исключения для query vars фильтров;
- не включён ли агрессивный minify, который ломает скрипты фильтрации;
- не подменяет ли CDN canonical или редиректы.
Проверка результата после внедрения
После правок не ограничивайтесь открытием одной страницы. Проверьте цепочку целиком:
- Откройте первую страницу каталога.
- Перейдите на вторую и третью страницу пагинации.
- Проверьте страницу с активным фильтром и сортировкой.
- Сравните заголовок, canonical и количество товаров на странице.
- Посмотрите ответ сервера через DevTools или
curl.
Пример быстрой проверки через консоль:
curl -I https://example.com/shop/page/2/
curl -I 'https://example.com/shop/?orderby=price'Если в ответе по-прежнему 404, а первая страница живая, значит проблема не в шаблоне вывода, а в rewrite rules, фильтре URL или конфликте с плагином.
Частые ошибки и как их исправить
- Используют
pageвместоpagedв архиве товаров. Для архивов и списков записей нужен именноpaged.pageчаще встречается на статических страницах с разбиением контента. - Забывают передать
max_num_pagesвpaginate_links(). В итоге ссылки рисуются, но ведут в никуда или обрываются раньше времени. - Вызывают
query_posts(). Это ломает основной запрос и часто создаёт побочные 404. Для каталога WooCommerce так делать не стоит. - Не сбрасывают кеш после правок ЧПУ. После смены slug старые URL могут продолжать жить в кеше и давать ложную картину.
- Меняют товары через
pre_get_postsбез проверкиis_main_query(). Тогда правка цепляет не только магазин, но и связанные блоки, виджеты или AJAX-запросы.
Практические советы по безопасности и производительности
Если проблема решается кодом, держите правки в дочерней теме или в небольшом mu-plugin, а не в шаблоне, который легко потерять при обновлении. Для каталога с фильтрами полезно:
- не делать лишние запросы в цикле товаров;
- не использовать тяжёлые meta_query без необходимости;
- проверять, что кеш не хранит персонализированные страницы;
- не отключать canonical и не подменять его вручную без причины;
- после правок тестировать не только desktop, но и мобильный шаблон, если там отдельная навигация.
Если у вас несколько фильтров и страниц каталога, полезно отдельно проверить, не конфликтует ли тема с плагином оптимизации. В таких случаях иногда помогает не «ещё один фикс», а аккуратная чистка дублей и лишних скриптов. Из готовых инструментов для этого можно посмотреть Clearfy Pro: https://wpshop.ru/plugins/clearfy.
Когда проблема не в WooCommerce
Если 404 появляется только на части URL, проверьте конфликт с плагином фильтрации, редиректами и языковым плагином. Иногда магазин работает, но плагин переводов или SEO-модуль переписывает URL так, что страница 2 становится недоступной. В этом случае полезно временно отключить по одному плагину и повторить проверку на чистом кеше.
Если после всех шагов 404 остаётся только на второй странице и выше, а первая страница открывается, почти всегда виноват либо неправильный paged, либо rewrite rules, либо кеш, который не различает страницы пагинации. Начинать диагностику стоит именно с этих трёх точек — это быстрее, чем искать проблему в шаблоне товара.