Диагностика проблемы: почему возникает ошибка 404 при пагинации нескольких WP_Query
Ошибка 404 при переходе по страницам пагинации — частая проблема, если на одной странице WordPress используется несколько запросов WP_Query с пагинацией. Основная причина — конфликт параметров paged и неправильная обработка URL-параметров WordPress. Параметр paged отвечает за номер текущей страницы пагинации, но WordPress по умолчанию поддерживает только один глобальный параметр пагинации для основного запроса.
Если вы делаете второй или третий WP_Query с пагинацией на той же странице, и не обрабатываете номера страниц для каждого запроса отдельно, система пытается найти страницу архива для номера, который не существует, и выдает 404 ошибку.
Пошаговое решение: настройка нескольких WP_Query с пагинацией без ошибки 404
1. Используйте разные параметры пагинации для каждого запроса
Нельзя использовать один и тот же параметр paged из get_query_var('paged') для всех запросов. Для каждого WP_Query с пагинацией создайте свой параметр в URL, например paged1, paged2.
2. Получите текущую страницу из своего параметра
$paged1 = max( 1, get_query_var('paged1') ? get_query_var('paged1') : 1 );
$paged2 = max( 1, get_query_var('paged2') ? get_query_var('paged2') : 1 );3. Зарегистрируйте кастомные параметры в WordPress
WordPress по умолчанию не знает про paged1 и paged2. Чтобы они распознавались и не приводили к 404, добавьте в functions.php:
function add_custom_paged_query_vars( $vars ) {
$vars[] = 'paged1';
$vars[] = 'paged2';
return $vars;
}
add_filter( 'query_vars', 'add_custom_paged_query_vars' );4. Создайте WP_Query с использованием своих параметров
$args1 = [
'post_type' => 'post',
'posts_per_page' => 5,
'paged' => $paged1
];
$query1 = new WP_Query( $args1 );
$args2 = [
'post_type' => 'product',
'posts_per_page' => 4,
'paged' => $paged2
];
$query2 = new WP_Query( $args2 );5. Выведите пагинацию с правильными ссылками
При выводе пагинации используйте функцию paginate_links() с параметром format, который учитывает ваш кастомный параметр пагинации:
echo paginate_links([
'base' => add_query_arg('paged1', '%#%'),
'format' => '',
'current' => $paged1,
'total' => $query1->max_num_pages
]);
// Аналогично для второго запроса
echo paginate_links([
'base' => add_query_arg('paged2', '%#%'),
'format' => '',
'current' => $paged2,
'total' => $query2->max_num_pages
]);Проверка результата после внедрения
- Откройте страницу с двумя WP_Query и пагинацией.
- Перейдите по ссылкам пагинации каждого блока.
- Проверьте, что URL меняется с
?paged1=2и?paged2=3соответственно. - Убедитесь, что нажатие по пагинации не приводит к 404 ошибке.
- Проверьте, что выводятся корректные записи соответствующей страницы.
Частые ошибки и как их исправить
- Не зарегистрированы кастомные query vars: если не добавить
paged1и другие параметры через фильтрquery_vars, WordPress будет игнорировать их и выдавать 404. - Использование одного параметра paged для всех запросов: приводит к конфликтам, всегда используйте уникальные параметры для каждого WP_Query с пагинацией.
- Неправильный базовый URL в paginate_links(): если не использовать
add_query_arg()или задать формат неверно, ссылки пагинации будут некорректны. - Кеширование страниц: при использовании плагинов кеширования убедитесь, что разные страницы пагинации кешируются отдельно, иначе может показываться старая страница.
Практические советы по производительности и безопасности
- Для улучшения производительности ограничьте количество записей
posts_per_pageи используйте индексы для сложных запросов. - Используйте
pre_get_postsаккуратно, не меняйте глобальный запрос, если работаете с несколькими WP_Query. - При добавлении кастомных параметров в URL фильтруйте и валидируйте их, чтобы избежать XSS-атак.
- По возможности используйте AJAX для подгрузки пагинации, чтобы снизить нагрузку на сервер и избежать перезагрузки страницы.
Сравнение вариантов реализации пагинации с несколькими WP_Query
| Метод | Описание | Плюсы | Минусы |
|---|---|---|---|
Один параметр paged для всех запросов |
Использование стандартного параметра WordPress | Простая реализация | Конфликты, 404 на дополнительных запросах |
Разные query vars (paged1, paged2) |
Отдельные параметры пагинации для каждого WP_Query | Работает корректно, нет конфликтов | Требует регистрации параметров и корректной генерации ссылок |
| AJAX пагинация для каждого запроса | Подгрузка постов без перезагрузки страницы | Улучшенный UX, снижение нагрузки | Сложность реализации, требуется JS |