The Infinite Scroll SEO Problem Nobody Talks About
On this page
- The two-phase render reality, and why scroll loses
- Phantom pagination: the worst of both worlds
- The hybrid fix: a real, visible crawl path
- Self-referencing canonicals, and the rel=prev/next myth
- Ordering, and a platform leak to watch
- Why this is the argument that wins the UX debate
- The hidden CWV and back-button costs
- Frequently Asked Questions
- Sources
- Related posts:
Infinite scroll breaks indexing because Googlebot’s renderer does not fire scroll events, so anything your page loads in response to scrolling is invisible to Google. The Web Rendering Service executes JavaScript, but it does not scroll, click “load more,” or otherwise simulate the user actions your infinite scroll depends on. Only the items present in the initial mobile-first viewport get seen; everything below that, injected on scroll, effectively does not exist to the indexer. The resolution is a hybrid: keep the scroll experience for users, but give Googlebot a genuinely crawlable, self-canonicalizing pagination path it can follow without scrolling, and along the way fix the layout-shift, interaction, and back-button costs infinite scroll quietly introduces.
The two-phase render reality, and why scroll loses
Googlebot processes a page in two phases. First it fetches the HTML and extracts the links present in that server-rendered response. Later, the page enters a render queue where the WRS executes JavaScript and the post-JS DOM is evaluated, often after a delay. The trap is that the WRS renders but does not interact: it does not scroll, so the onScroll handler that triggers your next batch of items never fires, and those items are never injected into the DOM the renderer sees.
You can confirm exactly what Google sees. Run the collection or listing page through URL Inspection and read the rendered HTML, then count how many items appear. Count specifically against the initial mobile viewport, because indexing is mobile-first, and a desktop view that shows more before scrolling will mislead you. If only the first handful of products render and the rest are gone, that is the entire problem in front of you.
Phantom pagination: the worst of both worlds
A common half-fix makes things worse. Teams enable ?page=2, ?page=3 and so on as working URLs, but never link to them anywhere in the rendered markup, the only navigation is the scroll. Now the paginated URLs exist but are undiscoverable: Google has no link to follow to reach them, and the scroll it cannot trigger is the only path. You have the maintenance and duplication surface of pagination with none of its crawlability benefit. A paginated URL that nothing links to is invisible.
The hybrid fix: a real, visible crawl path
The resolution is to provide genuine pagination links that Googlebot can follow, alongside the scroll users enjoy:
- Render real, visible pagination links (numbered pages or next-page links) in the DOM. They must be actually visible, not
display:none, because the point is that they are a legitimate crawl path a user could also use. This is not cloaking; you are showing the same navigable links to users and crawlers. - Prefer server-rendered links so they are present in phase one, before the render queue, which is when Google does its fastest discovery. A link that only appears after JS execution is found later, if at all.
- Keep the scroll as a progressive enhancement layered over the crawlable pagination, rather than as the sole mechanism.
Done this way, every item is reachable through a standard link, and the scroll is just a nicer way for humans to traverse the same set.
Self-referencing canonicals, and the rel=prev/next myth
The fatal mistake on paginated series is canonicalizing every page back to page one. That tells Google that pages two and beyond are duplicates of page one, so it drops them, and you lose the very items pagination was meant to expose. Each paginated page should carry a self-referencing canonical: page two canonicalizes to page two. Each page is its own distinct set of items, not a copy of the first.
And do not reach for rel="prev" and rel="next" to stitch the series together. Google deprecated those signals in 2019 and does not use them for pagination; they carry no SEO weight with Google. Treat each paginated URL as a standalone, self-canonical page and let internal links express the sequence.
Ordering, and a platform leak to watch
Two more correctness issues:
- Scroll order and pagination order must match. If the items a user sees while scrolling differ from the items behind
?page=2, products can fall out of their category context entirely, indexed under no page or duplicated awkwardly. The crawlable pagination must reflect the same sequence the scroll presents. - Watch for platform endpoint leaks. Some platforms expose listing data through JSON endpoints used to power the scroll, and on Shopify, for example, collection and product JSON endpoints plus variant URLs can create duplicate, crawlable surfaces you did not intend. Treat this as a concrete example to check on your stack rather than a universal rule, and verify how your platform exposes its scroll data.
Why this is the argument that wins the UX debate
The reason to lead with the rendering mechanism rather than with a ranking complaint is that it is testable and undeniable. A UX designer can dismiss “infinite scroll is bad for SEO” as an opinion, but they cannot dismiss the rendered HTML in URL Inspection showing four products where the page has three hundred. Make the demonstration concrete: pull the rendered DOM, count the items, and show that the catalog below the initial viewport is simply absent from what Google evaluates. Framed that way, the hybrid pagination is not a concession the UX team makes to SEO; it is a correctness fix for a page that is currently shipping most of its content into a void. The scroll experience survives intact, because the pagination links coexist with it rather than replacing it, so there is no real tradeoff to litigate once everyone is looking at the same evidence.
The hidden CWV and back-button costs
Infinite scroll’s SEO damage is not only crawlability; it carries page-experience costs that give you an argument the UX team will accept:
- Cumulative Layout Shift from content injected as the user scrolls, if space is not reserved for incoming items, against a CLS target of 0.1 or below at the 75th percentile.
- Interaction to Next Paint strain from heavy scroll handlers; INP replaced FID in March 2024 as a Core Web Vital, with a target of 200ms or below, and a busy scroll listener firing constantly is exactly the kind of work that degrades it.
- Back-button and bfcache breakage. A user who scrolls deep, clicks an item, then hits back often lands at the top of a freshly reset list rather than where they were, because the scroll state was not preserved. That is both a real usability failure and a signal of a poor experience.
One caution on implementation: behavior of an Intersection Observer under the WRS is not something to assume renders reliably. Test your specific implementation in URL Inspection rather than trusting that an observer-based loader is seen.
Frequently Asked Questions
Does Googlebot scroll the page to load infinite-scroll content?
No. The Web Rendering Service executes JavaScript but does not fire scroll events, click “load more,” or otherwise interact, so content injected on scroll is never added to the DOM it evaluates and is effectively invisible. Verify what is actually rendered by checking the rendered HTML in URL Inspection against the initial mobile viewport.
Should each paginated page canonicalize to page one?
No. Canonicalizing every page to page one tells Google the later pages are duplicates and it drops them, taking their items with them. Use a self-referencing canonical on each page, and do not rely on rel=prev/next, which Google deprecated in 2019 and no longer uses for pagination.
Sources
JavaScript SEO basics and how Google renders JavaScript (Google Search Central): https://developers.google.com/search/docs/crawling-indexing/javascript/javascript-seo-basics
Core Web Vitals and INP (web.dev): https://web.dev/articles/inp