Infinite scroll loads more items as a visitor moves down the page. Social feeds use it, and so do many shops, news sites and image galleries. Visitors like it because there is nothing to click. The risk is that a search engine does not scroll. If the extra items only appear after a scroll event, a crawler may see just the first batch and never learn that the rest exist.
Infinite scroll SEO is the work of keeping the smooth experience while giving crawlers another way in. The approach is simple. Behind the scrolling feed, every chunk of items also lives at its own paginated URL, those URLs are linked together with ordinary anchors, and the browser address updates as the visitor reaches each chunk. This guide is written for developers and site owners who run a feed, a category page or a gallery that loads on scroll. By the end you will have a design to implement and a way to test it.
Making a feed crawlable does not make search engines index every item. It removes technical barriers so that indexing is possible.
Before you begin
You will need:
- The page or component that loads items on scroll, and the endpoint that supplies them.
- Developer access to change templates and front-end JavaScript.
- A Search Console property for the site so you can run URL Inspection live tests.
- A browser with developer tools, and about half a day for a first implementation on one section.
Test on a staging copy or a single section first, because this work touches how your pages are built and linked. Keep a backup of the templates you change.
Why infinite scroll causes trouble
Google's guidance on lazy-loaded and infinite scroll content states that Google Search does not interact with your page. It does not scroll in the way a visitor does and it does not click. Content that loads only after such an action will not be seen unless it loads automatically when it enters the visible area.
Google's pagination guidance adds that its crawlers generally follow <a> elements with an href, and that load-more and infinite scroll patterns are usually built with JavaScript. Google says such pages need the JavaScript SEO practices it describes, and it suggests a sitemap as another way to expose all items.
So there are three separate questions to answer:
- Can a crawler find the URL of the second, third and later chunk of items?
- Does each of those URLs return the same content every time?
- Does the content of the first view load without a user action?
The steps below solve each in turn.
Step-by-step instructions
Step 1: Choose a paginated URL for every chunk
Decide how the feed divides into pages, for example 20 items per page, and give each page a persistent URL:
https://example.com/photos/?page=1
https://example.com/photos/?page=2
https://example.com/photos/?page=3
Google's guidance recommends absolute numbers like these. Avoid relative values such as ?date=yesterday or ?since=latest, because the same URL would then return different items on different days. Each URL must show the same content each time it is loaded, so a visitor or a crawler arriving at ?page=12 sees a stable set. Do not store the position in a fragment such as #page=12, because Google ignores fragments.
If items are added at the top often, page boundaries shift. Use a stable ordering and a fixed page size where you can, and accept that some drift is normal for a live feed.
What success looks like: each ?page=n address, opened on its own in a new tab, returns a complete page of items.
Step 2: Render each paginated URL on the server
For every paginated URL, make the server return the HTML for that chunk of items, including its links. Do not leave the content to be built by a script after the page loads if you can avoid it. Google can render JavaScript, but rendering happens in a separate step that can run some time after crawling, so server-rendered output is the safest way to make sure the items and links are present.
The scroll behaviour can then be a layer on top. A visitor who has JavaScript gets the endless feed. A crawler, or a visitor whose script failed, gets ordinary pages.
What success looks like: with JavaScript disabled, ?page=2 still shows its items.
Step 3: Put real links between the pages
Add anchors that link each page to the next one, and ideally to the previous one:
<ul id="feed">
<!-- items 1 to 20 -->
</ul>
<nav aria-label="More photos">
<a href="/photos/?page=2" id="next-page">Show more photos</a>
</nav>
Google says it finds new URLs by following <a href> links, so this anchor is what lets a crawler walk from page 1 to page 2 and on. Your script can intercept clicks on this link, or trigger the same load when the visitor nears the bottom, and fetch the next chunk without a full reload. Without the script, the link still works as a normal link.
Do not use <a href="#"> with a click handler, a pseudo-URL that runs a script instead of naming a page, or a bare <button>. These give the crawler no address to request. See Pagination SEO Best Practices for more on the link patterns and canonical tags that paginated sequences need.
What success looks like: the page source (View Source, not the live inspector) contains an <a href> that points at the next chunk.
Step 4: Load content when it enters the viewport, not on a user action
If you use lazy loading inside each chunk, trigger it by visibility. Google lists three acceptable methods: browser-native lazy loading for images and iframes, the IntersectionObserver API (with a polyfill where needed), or a JavaScript library that loads content when it enters the viewport.
Here is a small IntersectionObserver example that loads the next chunk when a sentinel element comes into view:
const sentinel = document.querySelector('#next-page');
const observer = new IntersectionObserver(async (entries) => {
if (!entries[0].isIntersecting) return;
const url = sentinel.getAttribute('href');
const html = await (await fetch(url)).text();
// insert the new items, then update the link to the following page
}, { rootMargin: '400px' });
observer.observe(sentinel);
Do not wait for a scroll event handler that needs a real scroll or a click before loading anything. Do not lazy-load content that visitors see the moment the page opens, because that slows it down.
For images inside the feed, use browser-native loading="lazy" on images below the first screen, keep the image URL in the src attribute of an <img> element, and leave the first screen of images unlazy. Google says that image and video URLs appearing in the src of <img> or <video> in the rendered HTML means the setup is working.
What success looks like: the first chunk of items is in the rendered HTML without any scrolling or clicking.
Step 5: Update the address bar with the History API
When a new chunk becomes the main thing on screen, update the browser URL so the visitor can refresh, bookmark or share the right spot. Google recommends the History API for this.
history.replaceState({ page: 3 }, '', '/photos/?page=3');
Use replaceState as the visitor scrolls past chunks, so the back button is not flooded with an entry per chunk, and pushState when a deliberate navigation happens. Update the page title if it carries the page number. Never use fragment routing such as #/photos/3 for this, since Google says to use the History API rather than fragments.
What success looks like: after scrolling to the third chunk and reloading the page, the browser shows page 3 and not the top of the feed.
Step 6: Add self-referencing canonicals and a sitemap path
Each paginated URL should carry its own canonical tag, not a canonical pointing at page 1. Google's pagination guidance says not to use the first page of a sequence as the canonical for the others.
Also list the individual item pages (the products, photos or articles) in your XML sitemap. Google lists a sitemap as a way to expose items that load incrementally. The sitemap is only a hint to Google, so keep the links in the page as well. See How to Create a Valid XML Sitemap.
What success looks like: view-source on ?page=3 shows a canonical for ?page=3, and the sitemap lists the item pages.
Step 7: Test as a crawler would
In Search Console, use the URL Inspection tool on ?page=1 and on a deep page such as ?page=9. Run the live test, open the rendered HTML, and look for the items and for the <a href> to the next page. Google recommends this check for lazy-loaded content. Fix anything missing and test again.
Then test without any search tool. Turn JavaScript off in your browser, load /photos/, and click through pages with links alone. If you can reach page 9 using only links, a crawler can too. For deeper checks on scripts that fail, see Find and Fix JavaScript Console Errors.
What success looks like: the live test shows the same items a visitor sees for that page, and the link chain works with JavaScript off.
Alternatives to endless scrolling
Google's documentation describes three patterns: numbered pagination, a "load more" button and infinite scroll. Numbered pagination shows visitors how big the list is and where they are, but its controls are more complex. Load more and infinite scroll keep everything on one page, but they cope poorly with very large result sets. If your list is large, or if your visitors often need to return to a specific spot, numbered pagination or a "load more" button that is a real link may serve them better than a fully endless feed. This is a product decision, and SEO is one input among several.
Final verification checklist
- Each chunk of items has a stable, absolute-numbered URL such as
?page=3. - Every paginated URL returns its items and links in server-rendered HTML.
- Each page has an
<a href>to the next page that works without JavaScript. - Content loads when it enters the viewport, not after a click or scroll event.
- The address bar updates through the History API as visitors move through chunks.
- Each paginated URL has its own canonical tag.
- Item pages are listed in the XML sitemap.
- A live URL Inspection test of a deep page shows the items and the next-page link in the rendered HTML.
Common mistakes to avoid
- Only a scroll listener loads items. Crawlers do not scroll. Provide paginated URLs and links as well.
- "Load more" is a button with no URL. Make it an anchor with an
hrefthat the script enhances. - Fragment-based routing.
#/page/4is not reliably handled. Use real paths or query strings with the History API. - Relative page parameters. Values like
?date=yesterdaychange over time. Use fixed page numbers. - Every chunk canonicalised to page 1. That asks Google to ignore the later chunks. Use self-referencing canonicals.
- Lazy loading the first screen. It delays what visitors see first. Keep above-the-fold content eager.
- Image URLs held only in a
data-attribute. If the rendered HTML has nosrcon the<img>, the images may not be found. Check the rendered output. - Never testing the rendered HTML. A page that looks right in your browser can still be empty to a crawler. Run the live test.
Frequently asked questions
Does Google scroll the page to load more items?
Google states that Google Search does not interact with your page. Do not depend on scrolling to reveal content. Load by visibility and provide linked URLs.
Can I keep infinite scroll and still rank pages 2 to 20?
You can keep the experience, as long as each chunk is also reachable at its own URL by an ordinary link. Whether Google chooses to index those URLs is up to Google, and nothing here promises it.
Should I noindex the paginated chunks?
Usually not, because a noindex page is dropped from results and the point of the chunks is to expose the items. Use noindex only on variants such as odd sort orders that you do not want in search.
Is IntersectionObserver safe for SEO?
Yes. Google lists it among the acceptable ways to load content when it comes into view. What matters is that the load does not need a click or a real scroll.
What about a very large feed of millions of items?
Google notes that load-more and infinite scroll cope poorly with very large result sets. Consider adding category pages, search, and linked item pages so that items are discoverable by other routes.
Related guides
- Pagination SEO Best Practices: Paged Lists Google Can Crawl
- JavaScript SEO: Server Rendering, Client Rendering and Crawlers
- Lazy Loading Images for SEO: Defer Images Without Hiding Them
- Internal Linking Strategy: Link Your Pages for People and Crawlers
- How to Create a Valid XML Sitemap for Your Website
Official references
- https://developers.google.com/search/docs/crawling-indexing/javascript/lazy-loading
- https://developers.google.com/search/docs/specialty/ecommerce/pagination-and-incremental-page-loading
- https://developers.google.com/search/docs/crawling-indexing/links-crawlable
- https://developers.google.com/search/docs/crawling-indexing/javascript/javascript-seo-basics
Next step: See how Crawvix checks a website and capture a baseline once scanning opens. This guide provides technical information, not a guarantee of rankings, traffic or index inclusion.
Crawvix Editorial Team
· Published October 29, 2026 · Last updated October 29, 2026 · 10 min read