Pagination for Large Product Catalogs

After rel='next'/'prev' deprecation, the patterns that work for SEO

Enric Ramos · · 7 min read
a close up of a book with an open page

Google deprecated rel="prev" and rel="next" for pagination in March 2019. The announcement confused the SEO community — these tags had been the standard paginated-series signal for a decade. Google's position: they had stopped using them as indexation signals years earlier. You had been optimizing for a signal Google wasn't reading.

After deprecation, pagination patterns split into a few workable options, each with trade-offs. This article covers the four patterns that work for ecommerce catalogs, the decision matrix per catalog size, and the common implementation bugs that quietly harm SEO.

The four patterns

Pattern 1: Classic pagination (?page=2, ?page=3)

Each page is a distinct URL with its own content (the products assigned to that page). Navigation links ("previous 1 2 3 next") between pages.

/running-shoes           — page 1 (24 products)
/running-shoes?page=2    — page 2 (24 products)
/running-shoes?page=3    — page 3 (24 products)

SEO handling options:

  • Self-canonical each page + noindex, follow on pages 2+: pages stay crawlable (links flow) but don't compete for rankings.
  • Canonical page 2+ to page 1: all signals consolidate on page 1. Google deprecated this pattern officially; still works de facto for many sites.
  • Self-canonical each page + index all: pages 2+ can rank for their own content. Usually not what you want — deep paginated pages rarely rank meaningfully.

Default recommendation: self-canonical + noindex, follow on pages 2+. Page 1 gets the ranking; deep pages stay discoverable.

Pattern 2: Infinite scroll with URL updates (hybrid)

User scrolls, more products load via JavaScript. As products load, URL updates (via History API) to reflect the current "page."

/running-shoes           — initial
/running-shoes?page=2    — after first scroll batch
/running-shoes?page=3    — after second scroll batch

Each page state is directly accessible by URL — ?page=5 loads page 5 server-side if hit directly.

SEO considerations:

  • Server-side rendering of each page state is required for Googlebot to see the content.
  • URL updates must use history.pushState() — URL fragments (#page=2) don't work for SEO.
  • Deep page access via direct URL should return the page's products in the initial HTML (pass 1).

Pros: best UX (seamless scroll) + SEO (URLs are crawlable). Cons: complex implementation; easy to break on edge cases.

Pattern 3: View-all page

Single URL with all products, no pagination.

/running-shoes?view=all   — all 127 products on one page

Pros: one URL, all signal consolidated, trivial SEO. Cons: performance collapses past ~500 products (slow load, high LCP).

Viable when: catalog under 300-500 products per category. Anything larger kills page load.

Pattern 4: Load-more button

User sees initial page of products. "Load more" button fetches the next batch via AJAX.

/running-shoes   — shows products 1-24
[click load more]
/running-shoes   — still, but DOM now has products 1-48

If the button doesn't update the URL, Googlebot sees only the initial 24 products. If it does update, it's effectively Pattern 2 (infinite scroll with URL updates).

Pros: simple UX. Cons: without URL updates, hides content from crawlers. Pure load-more (no URL change) is SEO poison for paginated content.

Decision matrix

Catalog size per category Recommended pattern
Under 50 products Classic pagination OR view-all
50-300 products Classic pagination with noindex on pages 2+
300-2,000 products Classic pagination with noindex on pages 2+, OR infinite scroll with URL updates
2,000+ products Classic pagination with proper sitemap per page

The size thresholds are rough; adjust for per-product page weight and performance constraints.

Implementation details

URL structure

Two formats:

Query parameter: /category?page=2 Path segment: /category/page/2

Both work. Query parameter is more common and simpler; path segment looks cleaner and is easier for analytics filtering. Pick one and stick with it.

Avoid: hash-based pagination (/category#page=2) — not crawlable. Don't use.

Canonical on paginated pages

For page 2+ with noindex, follow:

<!-- On /category?page=2 -->
<link rel="canonical" href="https://example.com/category?page=2">
<meta name="robots" content="noindex,follow">

Self-canonical to itself; noindex prevents ranking; follow allows link flow.

Not recommended: canonical page 2+ to page 1.

<!-- WRONG — canonicaling page 2 to page 1 -->
<link rel="canonical" href="https://example.com/category">

This tells Google page 2 is a duplicate of page 1, which it isn't (different products). Google ignores; may trigger quality signals.

Page size considerations

Typical products-per-page:

  • Small catalogs (< 100): 20-50 per page. One or two pages max; pagination matters less.
  • Medium catalogs (100-1000): 24-48 per page. Standard grid layouts.
  • Large catalogs (1000+): 48-100 per page. Users want to scroll; pages should be substantial.

Too small (12 products per page) means deep pagination — 100+ pages per category, most of which have thin content. Too large (200+ per page) means slow load on each page.

24-48 is the common sweet spot.

Sitemap inclusion

Which paginated URLs to include in the XML sitemap:

Include: page 1 (which is the canonical entry point for the category). Exclude: pages 2+ when they're noindexed. Listing a noindex URL in the sitemap is contradictory.

If you index all paginated pages (Pattern 2 with each page canonical to itself), then include all pages in the sitemap. But this is rarely the right setup.

Internal linking to paginated pages

From the category page, link to page 2 with normal HTML (<a href="?page=2">2</a>), not JavaScript-only navigation. Googlebot discovers pagination links from HTML.

Deep internal links from product pages usually don't need to point to paginated categories — link to the base category URL, which users can then paginate through.

Performance considerations

Pagination performance has three components:

1. Initial page load (LCP): Page 1 of a category should load in under 2.5 seconds at p75 (CWV threshold). Product images are the typical LCP element; preload the first few, lazy-load the rest.

2. Pagination transition (INP): Clicking to page 2 triggers a navigation. If it's a full page reload, no INP impact (it's a new page). If it's JavaScript navigation without page reload, the transition must not block the main thread for >200ms.

3. Scroll performance (for infinite scroll): Adding DOM nodes on scroll should not cause layout thrashing or main-thread blocking. Use Intersection Observer for lazy-loading triggers; avoid JavaScript that runs on every scroll event.

Common mistakes

Load-more without URL updates. Googlebot sees only the initial batch. Content past that batch is invisible. Always update URLs on pagination.

Conflicting canonical + noindex on the same page. A paginated page that canonicals elsewhere and noindex's confuses signal. Pick one.

View-all URL without handling its interaction with paginated URLs. If /category?view=all and /category?page=1 both exist and both indexable, you have duplicate content. Pick one as canonical.

Not paginating at all on a 2000-product category. One massive page with 2000 products. Performance collapses; LCP fails; users bounce. Paginate.

Paginated URLs using # fragments. /category#page=2 is not a distinct URL to Google. Content past page 1 is unreachable.

Forgetting to update page-specific metadata. Page 2 shows "Running Shoes - Page 2" in the <title> but the same description as page 1. Update both per page for uniqueness.

Page 1 canonical question

A related debate: should /category and /category?page=1 both exist?

Common implementation: /category is page 1; /category?page=1 301 redirects to /category. This avoids duplicate content.

Alternative: both URLs exist, both canonical to /category. Acceptable but adds a URL variant to manage.

Default: redirect ?page=1 to the bare URL. Simpler.

Frequently asked questions

Does infinite scroll hurt SEO?

Only if it doesn't update the URL as products load. With URL updates and server-side rendering of each state, infinite scroll is neutral for SEO. Without URL updates, it's poison.

Should I include ?page=2 URLs in my sitemap?

Only if those URLs are meant to be indexable. For the standard noindex-on-page-2+ setup, exclude from sitemap.

What about rel="prev" and rel="next"?

Google stopped using these for indexation in 2018-ish and deprecated the signal announcement in 2019. Still valid HTML, but has no SEO effect. Some sites include them for completeness; most don't bother.

How many products should fit on page 1?

24-48 is typical. Fewer loses shelf-space for above-the-fold product visibility. More makes initial load slow.

Can I use pagination and filters together?

Yes, carefully. A filtered paginated URL (/running-shoes/nike?page=2) is the intersection — often high-complexity. See faceted-navigation-seo for the filter-URL strategy.

Related articles

Red 'buy now!' button on a computer keyboard.

Out-of-Stock Product Pages: 4 Strategies Compared

Most ecommerce sites handle out-of-stock products inconsistently, destroying seasonal rankings. The four viable strategies (keep with notice, 301 to category, 410 Gone, 404) each fit specific scenarios. Here's the decision tree and the reindexation implications.

· 7 min read
a white and black sign

Category Filters: UX vs SEO Trade-offs

Category filters are the UX feature with the most SEO footprint. Every filter selection is a potential URL. Most shouldn't be indexed, but the ones with real search intent should. The trade-off between UX flexibility and SEO cleanliness is worth deliberate design.

· 7 min read
Workflow diagram, product brief, and user goals are shown.

Product Schema: Variants, Availability, Ratings

Product schema is non-negotiable for ecommerce. Stars, prices, and availability in the SERP lift CTR 15-30%. But implementation mistakes — schema claiming features the page doesn't show, variant handling, availability lag — trigger manual penalties. Here's the implementation that works.

· 7 min read