КейсыРастИИшка
Поисковое продвижение

Пагинация каталога: как совместить «показать ещё» и доступные URL

Обсудить задачу → Оставить заявку

Кнопка «показать ещё» часто подгружает товары без смены адреса, и ссылка на найденную позицию открывает у коллеги первый экран. Разберём, как закодировать порцию списка в URL и что проверить, чтобы продолжение не обрывалось молча.

Порция каталога должна иметь собственный URL, в котором закодированы фильтр, сортировка и смещение или курсор. Кнопка «показать ещё» оборачивается в обычную ссылку на следующую порцию, а скрипт лишь перехватывает клик для подгрузки без перезагрузки. Любая смена фильтра или сортировки обнуляет смещение и меняет адрес. Оговорка: доступность URL не гарантирует индексацию каждой порции.

Общий маршрут: от клика по кнопке до адреса порции
Общий маршрут: от клика по кнопке до адреса порции. Авторская схема 404ai.

Список товаров, который умеет продолжаться без кнопки «показать ещё»

Представьте условный магазин крепежа: каталог из 4 800 позиций, на странице по 24 карточки, а под последней — кнопка «Показать ещё». Покупатель находит нужный саморез, копирует адрес из строки браузера и отправляет коллеге. Коллега открывает ссылку и видит первые 24 позиции — то, что было на экране у отправителя, исчезло. Это не редкость и не баг конкретной платформы, а следствие того, как устроена выдача списка.

Механизм здесь простой: у каталога есть два разных представления одного и того же набора данных. Первое — то, что видит человек в браузере после серии кликов. Второе — то, что получает любой, кто пришёл по URL без этих кликов: поисковый робот, коллега, закладка, кнопка «назад». Если второе представление не содержит продолжения списка, страница формально существует, но фактически обрывается на первом экране. Дальше разберём, как сделать так, чтобы продолжение было и у человека, и у адреса, и чтобы эти два представления не разъезжались при каждом изменении сортировки.

Если ваша задача — проверить страницы каталога, на странице соответствующего направления 404ai можно посмотреть опубликованные возможности и оставить описание текущего процесса. Конкретные подключения, исходные данные и критерии приёмки согласуем отдельно.

Что именно ломается, когда продолжение живёт только в JavaScript

Классическая реализация «показать ещё» подгружает следующую порцию через запрос к серверу и вставляет карточки в DOM. Адресная строка при этом не меняется. Для человека всё работает: он нажимает, видит новые товары. Для всех остальных — нет. Робот, который не выполняет пользовательские клики, видит только исходные 24 карточки и не имеет никакого сигнала, что за ними есть что-то ещё. Даже если он умеет исполнять JavaScript, кнопка не нажимается сама по себе.

Google в документации о пагинации и добавочной загрузке прямо разделяет два подхода: постраничная навигация со ссылками и бесконечная прокрутка или подгрузка по кнопке. Для второго варианта рекомендуется обеспечивать доступ к следующим порциям через обычные ссылки, чтобы у каждой части списка был собственный адрес. Это не требование к дизайну, а требование к структуре: продолжение должно быть достижимо без исполнения пользовательского сценария.

Отдельная тонкость — что считать «страницей». Если каталог отсортирован по популярности и первые 24 позиции меняются каждую неделю, то URL /catalog/samorezy?page=2 будет указывать на разные товары в разные дни. Это нормально для живого каталога, но означает, что нельзя опираться на номер страницы как на стабильный идентификатор товара. Адрес страницы — это адрес среза списка в момент запроса, а не адрес конкретной позиции.

Рабочий объект: поля порции списка каталога
Рабочий объект: поля порции списка каталога. Авторская схема 404ai.

Отдельная порция каталога: что должно быть у каждой порции списка

Прежде чем трогать код, стоит зафиксировать, с чем мы вообще работаем. Порция списка — это не «экран», а объект с набором полей, которые должны быть согласованы между собой. Если хотя бы одно поле расходится с реальностью, продолжение начинает врать.

Поле объекта Что означает Типичная ошибка
Базовый набор Фильтры и категория, к которым применяется порция Фильтр применён в интерфейсе, но не в URL
Сортировка Порядок, в котором идут товары Сортировка меняется без смены адреса
Смещение Сколько позиций пропущено от начала набора Смещение считается от предыдущего клика, а не от начала
Размер порции Сколько карточек в этой порции Размер зашит в двух местах и расходится
Границы набора Есть ли ещё товары после этой порции «Показать ещё» показывается на последней порции
Адрес порции URL, открывающий ровно эту порцию URL повторяет первый список

Эта таблица — не бюрократия. Каждое поле соответствует конкретному вопросу, который задаёт либо человек, либо робот: «что я сейчас вижу», «что будет дальше», «можно ли это открыть заново». Когда все шесть полей согласованы, продолжение списка становится предсказуемым. Когда нет — появляются эпизоды вроде тех, что ниже.

Эпизод первый: коллега открывает ссылку и не находит товар

Условный менеджер по закупкам листает каталог подшипников, нажимает «Показать ещё» три раза, находит позицию на 70-м месте и копирует адрес. Адрес в этот момент — просто /catalog/podshipniki, потому что подгрузка не меняла URL. Коллега открывает ссылку и видит первые 24 позиции. Товара нет. Менеджер уверен, что «ссылка сломалась», коллега — что товара в каталоге нет.

Что должно было произойти: каждый клик по «Показать ещё» меняет адрес на что-то вроде /catalog/podshipniki?page=4 (или ?offset=72), а состояние списка восстанавливается из этого адреса при открытии. Тогда ссылка открывает ровно ту порцию, которую видел отправитель, — при условии, что сортировка и фильтры тоже закодированы в адресе. Если сортировка не закодирована, коллега получит четвёртую порцию уже другого порядка и снова не найдёт товар.

Здесь важно не перепутать две вещи: доступность продолжения и стабильность позиции. Первое мы обеспечиваем адресом. Второе — невозможно гарантировать в живом каталоге, и это честно стоит признать в интерфейсе: «порядок может меняться». Люди это понимают, когда предупреждены; они не понимают молчаливого исчезновения.

Эпизод второй: сортировка поменялась, а «показать ещё» осталось прежним

Условный покупатель заходит в каталог инструмента, листает две порции по популярности, потом переключает сортировку на «сначала дешёвые». Интерфейс перерисовывает первые 24 карточки, но кнопка «Показать ещё» помнит старое смещение — 48. Следующий клик подгружает позиции с 49-й по 72-ю уже в новом порядке, то есть товары, которые покупатель пропустил. Часть ассортимента он не увидит вообще.

Причина в том, что смещение хранится в состоянии компонента и не сбрасывается при смене сортировки. Правильное поведение: любое изменение базового набора или порядка обнуляет смещение и меняет адрес. Сортировка — часть адреса, а не отдельный переключатель поверх него. Тогда /catalog/instrument?sort=price_asc&page=2 всегда означает одно и то же: вторую порцию по возрастанию цены.

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

Проверка исключений: сортировка, возврат, пустая порция
Проверка исключений: сортировка, возврат, пустая порция. Авторская схема 404ai.

Как выглядит адрес, который честно описывает порцию

Есть два распространённых способа закодировать продолжение в URL: номер страницы и смещение. Номер страницы читаемее для человека, смещение точнее для машины. Выбор влияет на то, как ведёт себя каталог при добавлении товаров.

Способ Пример Плюсы Слабые места
Номер страницы ?page=3 Понятен человеку, короткий При вставке товаров границы сдвигаются
Смещение ?offset=48 Прямо соответствует запросу к данным Длиннее, менее очевиден
Курсор ?after=sku-12345 Устойчив к вставкам Требует стабильного ключа сортировки

Курсорная пагинация — самый устойчивый вариант для каталогов, где товары добавляются часто: следующая порция отсчитывается от последнего показанного товара, а не от числа. Но она требует, чтобы ключ сортировки был уникальным и стабильным. Если сортировка по популярности, а популярность пересчитывается, курсор тоже поедет. Универсального решения нет; есть выбор, который вы делаете осознанно под свой каталог.

Что бы вы ни выбрали, адрес должен быть воспроизводимым: открытие его в новой вкладке даёт ту же порцию при тех же фильтрах и сортировке. Это свойство проверяется за минуту и ловит большинство ошибок ещё до того, как их заметит покупатель.

Отдельная порция каталога: пустая последняя страница и сдвинувшиеся границы

Два случая ломают даже аккуратно сделанную пагинацию. Первый — последняя страница пуста. Товаров было ровно 48, покупатель нажимает «Показать ещё» на второй порции, сервер возвращает пустой список, интерфейс показывает пустоту. Формально всё правильно, фактически — тупик. Решение: перед показом кнопки знать, есть ли ещё товары, и не показывать её, когда набор исчерпан. Это требует либо отдельного запроса на количество, либо флага has_more в ответе.

Второй случай — новые товары сдвинули границы. Пока покупатель листал, в начало каталога добавили десять позиций. Смещение 48 теперь указывает на другие товары, и часть ассортимента покупатель пропустил, а часть увидел дважды. Это не ошибка реализации, а свойство смещения. Смягчить можно курсором или явным предупреждением, но полностью убрать — только перейдя на стабильный ключ сортировки.

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

Приёмочные тесты доступности продолжения списка
Приёмочные тесты доступности продолжения списка. Авторская схема 404ai.

Отдельная порция каталога на экране сотрудника

Каталогом пользуются не только покупатели. Менеджер, контент-редактор, оператор поддержки — все они листают те же списки и все они сталкиваются с теми же обрывами. Для них полезны несколько элементов, которых обычно не хватает.

Первый — индикатор текущей порции: «показано 48 из 4 800». Он снимает вопрос «а есть ли ещё» и заодно подсказывает, что список не бесконечен. Второй — явная кнопка «назад к началу списка», потому что после десяти кликов «показать ещё» вернуться к первым товарам иначе долго. Третий — сохранение состояния при возврате: если сотрудник открыл карточку товара и нажал «назад», он должен вернуться на ту же порцию, а не в начало. Это задача History API: состояние списка кладётся в историю, и возврат восстанавливает его.

Здесь есть тонкость с точки зрения доступности. Кнопка «показать ещё» должна быть настоящей кнопкой или ссылкой с понятной подписью, а не div с обработчиком. Ссылка на следующую порцию — лучший вариант: она работает и мышью, и с клавиатуры, и без скриптов. Подпись вроде «Показать ещё 24 товара» информативнее, чем просто «Показать ещё», потому что сообщает, сколько появится.

Как проверить, что продолжение действительно доступно

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

Проверка Как выполнить Что должно получиться
Ссылка на следующую порцию Открыть адрес второй порции в новой вкладке Видна ровно вторая порция, без кликов
Смена сортировки Переключить сортировку и нажать «показать ещё» Смещение сброшено, товары идут по новому порядку
Возврат назад Открыть товар из третьей порции и нажать «назад» Возврат на третью порцию, не в начало
Отключённый JavaScript Отключить скрипты и открыть каталог Ссылки на следующие порции работают
Последняя порция Дойти до конца набора Кнопка «показать ещё» исчезает, пустой страницы нет
Повтор адреса Открыть один и тот же адрес порции дважды Одинаковый набор при тех же фильтрах

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

Что говорят первоисточники и где заканчивается их применимость

Документация Google о пагинации и добавочной загрузке рекомендует обеспечивать ссылки на следующие порции и не полагаться на то, что робот нажмёт кнопку. Это ориентир для структуры, а не гарантия индексации: наличие ссылки не обещает, что каждая порция попадёт в индекс, и не обещает роста трафика. Материал Google о JavaScript и SEO объясняет, почему контент, появляющийся только после исполнения скрипта, может быть невидим для обхода, — отсюда и берётся требование к обычным ссылкам. Описание History API на MDN полезно для восстановления состояния при возврате: оно показывает, как класть состояние в историю и читать его обратно.

Все три источника описывают механику браузера и обхода, а не ваш каталог. Они не доказывают, что конкретная платформа умеет курсорную пагинацию или что ваш шаблон её поддерживает. Это проверяется отдельно — на вашем наборе данных, вашей сортировке и вашем шаблоне. Рекомендация здесь одна: относиться к источникам как к описанию ограничений, а не как к готовому решению.

Практикум: каталог фурнитуры на 1 200 позиций
Практикум: каталог фурнитуры на 1 200 позиций. Авторская схема 404ai.

Практикум: каталог мебельной фурнитуры на 1 200 позиций

Возьмём условный каталог фурнитуры: 1 200 позиций, по 30 на порцию, сортировка по умолчанию — по наличию, есть фильтр по типу. Задача — сделать так, чтобы продолжение списка было доступно и человеку, и адресу, и чтобы сотрудники не теряли место при возврате.

Шаг первый: закодировать в адресе фильтр, сортировку и смещение. Получается что-то вроде /catalog/furnitura?type=petli&sort=stock&offset=60. Открытие этого адреса должно вернуть порцию петель в порядке наличия, начиная с 61-й позиции. Шаг второй: при любом изменении фильтра или сортировки обнулять смещение и менять адрес. Шаг третий: в ответе сервера возвращать флаг «есть ещё», чтобы кнопка исчезала на последней порции и не вела в пустоту. Шаг четвёртый: обернуть кнопку в ссылку на следующую порцию, а скрипт пусть перехватывает клик и подгружает без перезагрузки — если скрипт не загрузился, ссылка всё равно работает. Шаг пятый: при открытии карточки товара класть состояние списка в историю, чтобы «назад» возвращал на ту же порцию.

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

Где заканчивается пагинация и начинается другая задача

Эта статья — про доступность продолжения списка, и только про неё. Она не отвечает на вопрос, как выбирать фильтры, как настраивать canonical для страниц с параметрами, как оценивать окупаемость доработок. Эти задачи соседние, но другие, и смешивать их в одном разборе значит потерять фокус. Если после проверок выяснится, что проблема не в продолжении, а в дублях адресов из-за фильтров, — это отдельный разговор.

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

Один шаг проверки, с которого стоит начать

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

Смежный вопрос разобран отдельно: Canonical для фильтров каталога: какой URL вы предлагаете поисковику.

Источники и границы разбора

Источники и статус проверки на 9 ноября 2026. Первичные документы поясняют указанные механизмы; доступность и границы каждого источника отмечены ниже. Методические рекомендации и условные примеры составляют самостоятельную часть разбора.

  1. Продвижение сайта с ИИ

    Опубликованное направление работы 404ai. Предлагаемая в статье методика не означает, что каждое описанное действие уже доступно без настройки; состав решения согласуется отдельно.

  2. Google: Pagination and incremental page loading

    Первичная документация указанного инструмента или механизма. Практические рекомендации и условные эпизоды статьи — самостоятельная методика, а не описание готовых функций 404ai.

  3. Google: JavaScript SEO basics

    Первичная документация указанного инструмента или механизма. Практические рекомендации и условные эпизоды статьи — самостоятельная методика, а не описание готовых функций 404ai.

  4. MDN: History API

    Первичная документация указанного инструмента или механизма. Практические рекомендации и условные эпизоды статьи — самостоятельная методика, а не описание готовых функций 404ai.

Частые вопросы

Почему ссылка на товар из глубины каталога открывает первый экран?

Подгрузка по кнопке часто не меняет адресную строку, поэтому URL описывает только исходные карточки. Каждый клик должен менять адрес на порцию с фильтром, сортировкой и смещением, а состояние списка восстанавливаться из этого адреса при открытии. Оговорка: при живом порядке позиция товара может сместиться между запросами.

Что делать, если после смены сортировки «показать ещё» подгружает пропущенные товары?

Смещение хранится в состоянии компонента и не сбрасывается при смене порядка. Нужно, чтобы сортировка была частью адреса, а любое её изменение обнуляло смещение и меняло URL. Тогда вторая порция по возрастанию цены означает ровно вторую порцию. Оговорка: проверять это нужно после каждого обновления шаблона каталога.

Как не показывать пустую последнюю страницу?

Сервер должен возвращать признак наличия следующих товаров, а интерфейс — скрывать кнопку, когда набор исчерпан. Иначе клик на последней порции даёт пустой список и тупик для покупателя. Альтернатива — отдельный запрос количества, но флаг в ответе проще. Оговорка: при живом каталоге границы могут сдвинуться между запросами.

Работает ли каталог с кнопкой «показать ещё» при отключённом JavaScript?

Нет, если продолжение существует только как обработчик клика: пользователь увидит обрезанный список. Кнопку нужно обернуть в обычную ссылку на следующую порцию, а скрипт пусть перехватывает клик как прогрессивное улучшение. Тогда без скриптов ссылка всё равно открывает следующую порцию. Оговорка: подпись ссылки должна сообщать, сколько товаров появится.

Как сохранить место в списке при возврате из карточки товара?

Состояние списка кладётся в историю браузера через History API, и возврат восстанавливает ту же порцию, а не начало каталога. Это особенно важно сотрудникам, которые листают длинные списки и открывают карточки. Без этого каждый возврат сбрасывает контекст. Оговорка: восстановление работает только если адрес порции воспроизводим при тех же фильтрах и сортировке.

404ai · задача вашей компании

Обсудим вашу задачу

Расскажите, какой результат нужен вашей компании и как задача решается сейчас. Уточним исходные данные, ограничения и подходящий формат работы. Состав работ, условия и сроки согласуем после оценки.

Укажите телефон или Telegram для ответа

Не присылайте пароли, ключи и клиентские базы. Для первого обсуждения достаточно описания задачи и контакта. Доступы и обработку данных согласуем отдельно, если они понадобятся.

Заявка принята. Свяжемся, уточним задачу и согласуем следующий шаг.

Можно также написать напрямую: Telegram 404ai.

Подробнее: Поисковое продвижение
Разбор задачи — бесплатноОтвет за 15 минут
Разобрать задачу