What pagination is and why it is not a detail
Pagination is the splitting of a long list into chunks. In a category with 2,000 products you cannot show everything at once: the page would weigh tens of megabytes and would not render on a phone. The list is cut into parts and the shopper moves through them in sequence.
It looks like a purely interface decision, but it touches three areas at once:
- SEO. Products a crawler never reaches do not get into the index. In a catalogue with poor pagination the first page of each category is indexed and nothing else — which literally means most of the assortment is invisible in search.
- UX. The pattern decides browsing depth, the ability to return to the right place in the list, and how the back button behaves coming out of a product page.
- Performance. The number of products per page sets the HTML weight, the number of images and the time to first render.
Three patterns and their consequences
| Criterion | Classic pages | Load more | Infinite feed |
|---|---|---|---|
| Separate URL per chunk | Every one has one | Yes, if the button is a link with href | Usually none |
| Crawler access | Full | Full when implemented correctly | First chunk only |
| Return from a product page | To the same page | Requires state restoration | Often resets to the top of the list |
| Browsing depth | Lower, each step is deliberate | Higher | Highest |
| Sense of the list ending | Yes, the last page number is visible | Yes | None, the shopper keeps scrolling |
| Access to the footer | Free | Free | Footer unreachable |
| Client-side load | Predictable | Grows with each load | Memory grows without limit |
| Analytics | Simple, one event per step | Clear | Depth hard to interpret |
In practice e-commerce most often ends up with a hybrid: a load-more button backed by a real <a href="?page=2"> link, plus a block of page numbers at the bottom. The shopper clicks the button and gets a chunk with no reload; the crawler walks the links like ordinary pagination.
An infinite feed implemented purely in JavaScript, without changing the URL, hides everything but the first chunk of products from search. In a 2,000-item category 40 products make it into the index — the rest do not exist as far as search is concerned. If the feed is required for product reasons, always add parallel access through page URLs.
SEO configuration for pagination
Self-referencing canonical. The page ?page=3 is canonicalised to ?page=3, not to the first page of the category. Canonicalising the whole pagination onto page one is the most frequent and most destructive mistake: the search engine stops counting the contents of deep pages and the products there drop out of the index. More on the mechanics in the article on the canonical tag.
Links in the HTML, not only in the script. If moving to the next page is handled by a click handler with no href attribute, then as far as the crawler is concerned there is no link. Pagination navigation must be ordinary links, with the JavaScript interception layered on top.
Sort orders and filters. Parameter combinations multiply the number of URLs:
40 pagination pages
x 8 sort orders
x N filter combinations
= hundreds of URLs for a single category
Sort parameters carry no unique content — they are a reshuffle of the same set of products. They get blocked from indexation (directives in robots.txt, a canonical from the sorted page to the unsorted one) and are kept out of the sitemap. Otherwise crawl budget goes on permutations instead of new product pages.
Unique metadata. The title and description on pagination pages must differ from the first page — usually by adding “— page N”. Fully identical metadata across 40 pages reads to a search engine as a duplication signal.
Depth. A category with 200 pagination pages is crawled badly: the crawler rarely reaches the last ones. If the assortment really needs that depth, split the category into subcategories and filter landing pages — they are both crawled better and capture demand.
Pagination and performance
The number of products per page is a compromise. Typical projects use 24–60 cards: that fits an acceptable response time without forcing too many clicks. Useful techniques:
- Card images through lazy loading, except above the fold.
- Fixed card dimensions so that loading a chunk does not shift the layout.
- With load-more, cap the total number of accumulated cards: after 5–7 loads offer a move to the next page, otherwise the browser starts to stutter on weaker devices.
- A back-to-top button appearing after the second load: in a long feed, getting back to the filters without one becomes a problem.
Pagination and personalised sorting
Listing personalization changes the product order for a specific shopper. Combined with pagination that creates a conflict which is easy to forget.
If the personal order is recalculated on every request, then between loading page 1 and page 2 the ranking has already changed: a product in position 18 may have moved up to position 5. The shopper sees it twice and never sees some other product at all. The symptom in production is complaints along the lines of “the same products on every page”.
The correct scheme:
Enter the category
-> compute the personal order once
-> store the ordered list of IDs in the session (key: user + category + filters)
-> pagination pages are sliced from THAT fixed list
-> recompute only on a filter change, a sort change or a new session
Additional requirements:
- Crawlers are served the default sort order, not the personalised one — otherwise the contents of
?page=2differ on every crawl. - The cache key for the personal order includes the filter set: a filter change is a new list, not a shift of the old one.
- The lifetime of the fixed order is the browsing session, usually 20–30 minutes.
Checklist
| Check | Expected |
|---|---|
| Canonical of page N | Points at itself |
| Pagination links | In the HTML, with an href attribute |
| Title and description | Differ from page to page |
| Sort orders | Blocked from indexation, out of the sitemap |
| Products per page | 24–60, a multiple of the grid width |
| Return from a product page | Opens the same page and list position |
| Personal order | Stable within a session and filter set |
| Indexation of deep pages | Spot-check URLs from pages 5, 10 and 20 in search |
| Pages per session after a pattern change | Measured before and after, together with listing conversion |
That last line deserves separate attention: moving from classic pages to an infinite feed almost always lifts page views and time on site, but that is not the same as more orders. A pattern change has to be judged on listing conversion and revenue, not on browsing depth.