# Google does not interact with your page, so scroll-loaded content never loads

> Google's lazy-loading documentation, carrying Last updated 2025-12-10 UTC, tells site owners to load content when it enters the viewport rather than when somebody scrolls, and gives the reason in one clause: Google Search does not interact with your page. The crawler pages published by OpenAI, Anthropic and Perplexity, fetched and searched on 14 August 2026, contain the words JavaScript, render, scroll, viewport and lazy zero times between them.

- Canonical page: https://lantad.co/blog/lazy-loading-and-crawlers-that-do-not-scroll
- This file: https://lantad.co/blog/lazy-loading-and-crawlers-that-do-not-scroll.md
- Last substantive update: 2026-08-14

## Key facts

- **Published:** 2026-08-14
- **Category:** Findings
- **Author:** Lantad
- **Length:** 3602 words
- **Takeaway 1:** Google's Fix lazy-loaded content documentation, carrying Last updated 2025-12-10 UTC and read on 14 August 2026, states that Google Search does not interact with your page, and on that basis tells site owners to load content whenever it is visible in the viewport rather than in response to a scroll or a click.
- **Takeaway 2:** The three implementations Google names on that page, being browser built-in lazy-loading for images and iframes, the IntersectionObserver API with a polyfill, and a JavaScript library that loads data when it enters the viewport, are grouped by one shared property: none of the three waits for a user action.
- **Takeaway 3:** Google's infinite scroll guidance asks for four things, and three of them are about URLs rather than about loading: a persistent unique URL per chunk, the same content at that URL on every load, sequential links between the chunks, and a History API update when a new chunk becomes the primary visible element.
- **Takeaway 4:** The crawler documentation published by OpenAI, Anthropic and Perplexity, fetched and string-searched on 14 August 2026, contains zero occurrences of JavaScript, render, scroll, viewport and lazy across all three pages, so a site owner planning a lazy-loading implementation has one vendor's documented behaviour to work from and three vendors' silence.
- **Takeaway 5:** Lantad's renderer scrolls three viewports, a setting named autoScrollViewports in core/src/config.ts rather than a measurement of anything, and attaches a note saying text below the last scrolled viewport may be undercounted whenever the document was still growing on the final pass.

## Summary

A page that reveals its content as the reader scrolls is not hiding anything from a person. The person scrolls, the content arrives, and the experience is usually better than the alternative of shipping forty product cards nobody asked for. The problem starts one layer down, at the question of what a client that never scrolls receives, because that client is the one deciding whether your page can be quoted back to somebody asking a question. This is a different failure from the ones that get discussed: nothing is blocked, nothing returns an error, robots.txt permits everything, and the text is genuinely on the page as far as the browser in front of you is concerned.

This post is a reading of published documentation rather than a measurement. [Google's Fix lazy-loaded content documentation](https://developers.google.com/search/docs/crawling-indexing/javascript/lazy-loading) was fetched and read on 14 August 2026, as were the crawler pages published by OpenAI, Anthropic and Perplexity, and every count below is a count of what those four pages say or do not say. Lantad has run no survey of lazy-loading implementations, holds no figure for how many sites defer their main text, and has measured nothing about how any [AI crawler](https://lantad.co/glossary/ai-crawler) behaves on a page that grows as it is scrolled. What it can add is the part that sits in its own source: what our renderer does about scroll-loaded content, what that is worth, and the note it attaches when scrolling three viewports was not enough.

## Google's documentation says Search does not interact with your page

The relevant page is short and it is not new. Under the heading Load content when it's visible in the viewport, Google lists three ways to defer loading: browser built-in lazy-loading for images and iframes, [the IntersectionObserver API](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API) together with a polyfill, and a JavaScript library that supports loading data when it enters the viewport. Then it says why those three and not others, in a single sentence that is the whole point of the page: the methods mentioned don't rely on user actions, such as scrolling or clicking, to load content, which is important as Google Search does not interact with your page.

That clause is worth separating from the advice around it. It is not a warning that deferred content might load slowly, or that a crawler might time out before it arrives. It is a statement that a specific category of event never happens. A scroll handler waits for a scroll. A click handler waits for a click. Neither occurs, so neither fires, so whatever they were going to insert into the document is not inserted, and the page that gets graded is the page as it stood before anybody touched it. The remedy Google offers works because it changes the trigger rather than the timing: [browser level lazy loading for images](https://web.dev/articles/browser-level-image-lazy-loading) and viewport intersection are both evaluated during layout, which a rendering client does, rather than in response to input, which it does not.

Two details on the same page are easy to skim past and both matter. The first is that Google tells you not to lazy-load content likely to be immediately visible when a user opens the page, which is a performance point rather than a crawling one and pulls in the opposite direction from the rest of the page. The second is the test it recommends: use the URL Inspection Tool in Search Console, look at the rendered HTML, and confirm your image or video URLs appear in the src attribute of the img or video elements. That is a check on the output of rendering, not on the source, and it is the same shape as the check that decides [prose parity](https://lantad.co/glossary/prose-parity) on a scan: compare what the raw document contained with what a rendering client ended up holding. The gap between those two is where deferred content lives, and it is also where client-side frameworks put everything, which is why [the React guide](https://lantad.co/fix/react) and [the Next.js guide](https://lantad.co/fix/nextjs) both start from the same comparison.

None of this is speculative and none of it is recent. The page carries Last updated 2025-12-10 UTC, and [Google's JavaScript SEO basics](https://developers.google.com/search/docs/crawling-indexing/javascript/javascript-seo-basics) has described the render step for years. What is worth noticing is how narrow the published commitment is: Google says it renders, and it says it does not interact. Those two facts together define exactly what a site has to do, and they are two more facts than anybody else has published.

## Infinite scroll needs four things, and three of them are about URLs

The second half of the same Google page covers infinite scroll, and the advice changes shape completely. Deferred images are fixed by changing the trigger. A feed that loads more content forever cannot be fixed that way, because there is no viewport large enough to contain an unbounded list, so [the same page](https://developers.google.com/search/docs/crawling-indexing/javascript/lazy-loading) asks for something else entirely: support paginated loading of the chunks.

Four requirements are listed. Give each chunk its own persistent, unique URL. Ensure the content shown on each URL remains the same every time it is loaded in a browser, which Google illustrates by recommending absolute page numbers such as a page=12 query parameter and warning against relative elements such as date=yesterday. Link sequentially to the individual URLs so that search engines can discover the URLs in a paginated set. And when a new chunk is loaded in response to the user scrolling and becomes the primary visible element, update the displayed URL using [the History API](https://developer.mozilla.org/en-US/docs/Web/API/History_API).

Read those four together and the pattern is clear: only the fourth is about scrolling at all. The other three are ordinary information architecture, and they would be good advice for a site with no JavaScript in it. What Google is actually asking for is that the infinite scroll be a presentation layer over a set of addressable pages, rather than the only way the content exists. [Google's pagination and incremental page loading guidance](https://developers.google.com/search/docs/specialty/ecommerce/pagination-and-incremental-page-loading) makes the same point at more length for ecommerce, where the pattern is most common and the cost of getting it wrong is a category page whose products are not individually reachable.

This is the version of the problem that a site owner can actually check without any tooling, and it is worth checking because the failure is invisible from inside the product. Load your listing page, scroll to the second batch, and look at the address bar. If it still shows the bare category URL, there is no address for the second batch, and there is nothing a crawler could have requested even if it wanted the rest. The relationship between what exists at a URL and what a client can retrieve from it is the whole of the first layer of the problem, and the ordering it sits in is the subject of [two layers that decide whether AI can read your site](https://lantad.co/blog/two-layers-decide-if-ai-can-read-your-site). Deferred content is a clean case of the second layer failing while the first is perfectly healthy: permission granted, status 200, body delivered, content absent.

## Three AI crawler pages never mention JavaScript, scrolling or the viewport

Google's page is useful because it makes a commitment. The obvious next question is what the vendors whose products actually quote your pages back to people have committed to, and the answer on 14 August 2026 is nothing at all on this subject.

[OpenAI's crawler overview](https://platform.openai.com/docs/bots) names four agents, being OAI-SearchBot for search, OAI-AdsBot for validating pages submitted as ads, GPTBot for training data and ChatGPT-User for user-initiated fetches, and describes each one in terms of robots.txt tokens, user-agent strings and published IP address files. [Anthropic's crawler article](https://support.claude.com/en/articles/8896518-does-anthropic-crawl-data-from-the-web), which carries a date of April 7, 2026, sets out three robots being ClaudeBot, Claude-User and Claude-SearchBot, with a column for what happens when you disable each. [Perplexity's crawler page](https://docs.perplexity.ai/guides/bots) names PerplexityBot and Perplexity-User and then spends most of its length on web application firewall configuration for Cloudflare and AWS.

All three pages were fetched and searched as delivered on 14 August 2026. Across the three, the words JavaScript, render, scroll, viewport and lazy occur zero times. The pages are not thin and they are not evasive about the things they do cover: between them they name nine agent tokens, publish IP range endpoints for each, and state plainly which agents are used for training and which are not. What they do not do is say whether the client behind any of those tokens executes a script, lays out a viewport, or would ever see an element that appears only after intersection. There is nothing in them to plan against.

That silence has a practical consequence, and it is not that these crawlers definitely cannot render. It is that a site owner has no documented behaviour to design for, so the only safe assumption is the conservative one. That assumption has support from at least one operator willing to state it, since [Common Crawl executes no JavaScript](https://lantad.co/blog/common-crawl-july-archive-no-javascript) and says so in its own FAQ, and the same conservative reading is what makes [a consent gate never open for a stateless crawler](https://lantad.co/blog/consent-gates-never-open-for-a-stateless-crawler): a page whose content depends on a machine doing something more than requesting a URL is a page that has made a bet. The pattern of vendors documenting tokens thoroughly and behaviour not at all is not confined to this subject either. It is the same gap that leaves [no crawler vendor documenting Retry-After](https://lantad.co/blog/no-crawler-vendor-documents-retry-after), and the same one that leaves [Googlebot's 2MB fetch limit](https://lantad.co/blog/googlebot-reads-the-first-two-megabytes) as the only published size ceiling anybody has. Working on [AI visibility](https://lantad.co/glossary/ai-visibility) means working against one vendor's documentation and several vendors' silence, and being clear about which is which.

## Our renderer scrolls three viewports, and says so when that was not enough

Everything above is somebody else's documentation. This section is our own source, and the numbers in it are settings that somebody chose rather than findings about the web.

The scanner renders with a real browser and then scrolls, because a renderer that does not scroll would produce exactly the undercount this post is about. The depth is a named constant, autoScrollViewports in core/src/config.ts, and its value is 3. Its comment in the file is one line: auto-scroll depth for lazy loaded content. The production path injects a short script that scrolls by one window height, waits 400 milliseconds, records document.body.scrollHeight, and repeats three times before scrolling back to the top. That is the whole mechanism, and 3 is a number chosen to fit inside a scan budget rather than a number derived from how far pages usually extend.

Which is why the more interesting piece of that code is not the scrolling but the accounting. The height samples are kept, and a pure function in core/src/render-notes.ts called scrollRevealedMore compares the last two: if the document was still growing on the final pass, the page had more to give than we asked for. When that is true the report carries a note, and the note is stored in the same file as a constant so it cannot drift from the condition that triggers it. It reads: the page kept loading content as it was scrolled (infinite or lazy loading), so text below the last scrolled viewport may be undercounted.

That note exists because the alternative is worse. A scanner that scrolls three viewports on an infinite feed and then reports a text count with no qualification has produced a confidently wrong number, and it will be wrong in the generous direction on short pages and the stingy direction on long ones, which is the sort of error that survives review because it looks like a measurement. Refusing to state a figure you cannot stand behind is the same principle as [withholding a grade](https://lantad.co/blog/why-we-withhold-a-grade) when a page could not be fetched, and it is written up in full in [our methodology](https://lantad.co/methodology).

Two limits are worth naming rather than leaving to be discovered. The first is that the two renderers sample at slightly different moments: the production path records the height after the pause, and the command line path records it immediately after the scroll and then pauses. Both answer the question of whether the document was still growing, and the code says which is which, but they are not byte identical and a page could in principle trip one and not the other. The second is that three viewports is three viewports. A feed that keeps loading past that point produces the note, not the content, and the note is an admission rather than a fix. The same honesty applies to the neighbouring case of [text inside shadow DOM](https://lantad.co/blog/shadow-dom-text-and-the-extractor), where the fallback that recovers the text runs in one of our two renderers and the post says so.

## What to check on your own site, in the order that settles it

Four checks, cheapest first, and each one answers a different question. None of them needs a tool from us, though [what GPTBot sees](https://lantad.co/tools/what-gptbot-sees) will do the first one against a named token if you would rather not use a terminal.

Start with the raw response. Request a content URL with no browser involved and search the body for a sentence from the middle of the page, not the headline and not the navigation. If it is there, deferred loading is not your problem and you can stop. If it is absent, the text arrives only after rendering, and everything downstream depends on a client that renders. Second, if the text is absent from the raw response, work out what triggers its arrival. Content that appears during layout is in a much better position than content that appears on a scroll event, and the difference is visible in the source: an IntersectionObserver call and an addEventListener for scroll are not the same bet. Third, for any feed or listing, scroll to the second batch and look at whether the URL changed. No change means no address, and no address means nothing to link to or request. Fourth, check whether the individual items are reachable from somewhere other than the infinite feed, which is usually a sitemap or a paginated archive, because that is the path a crawler will actually take.

The reason to run these in that order is that they get progressively more expensive and each one can end the investigation. It is the same ordering logic we use on a scan, and the same reason [our crawlability study](https://lantad.co/research/crawlability-study) reports what was measured and what was not rather than a single number. A finding of this kind is also worth separating from the ones people usually look for first. Deferred content is not a permission problem, so a robots.txt audit will not surface it, and it is not a discovery problem, so a sitemap will not surface it either. It shows up only when somebody compares the document a machine receives against the document a person sees, which is why [generative engine optimization](https://lantad.co/glossary/geo) work that stops at robots.txt and structured data stops one layer too early.

One closing caution against overcorrecting. Nothing here argues for deleting lazy loading. It is a real performance technique, Google's own page recommends implementations of it, and stripping it out to satisfy a crawler would be trading a measurable improvement for a speculative one. The argument is narrower: the trigger decides the outcome, viewport intersection is a trigger a rendering client produces and a scroll is not, and a feed needs addressable chunks whatever it does about triggers. That is three decisions, all of them made in your own source, all of them checkable this afternoon, and none of them requiring anybody at OpenAI or Anthropic or Perplexity to publish a page they have so far chosen not to write.

## Questions and answers

**Does Googlebot scroll a page?**

Google's Fix lazy-loaded content documentation, carrying Last updated 2025-12-10 UTC and read on 14 August 2026, states that Google Search does not interact with your page, and on that basis tells site owners to use loading methods that do not rely on user actions such as scrolling or clicking. The practical reading is that content whose arrival depends on a scroll event does not arrive. Google does render, and its recommended alternatives, being the built-in loading attribute, IntersectionObserver and viewport-aware libraries, all work because they are evaluated during layout rather than in response to input.

**Do GPTBot, ClaudeBot and PerplexityBot render JavaScript?**

Their published documentation does not say. The crawler pages published by OpenAI, Anthropic and Perplexity were fetched and searched as delivered on 14 August 2026 and contain the words JavaScript, render, scroll, viewport and lazy zero times between them. All three describe tokens, user-agent strings and IP ranges thoroughly and describe client behaviour not at all. Lantad has not measured what these clients execute, and treating the absence of a statement as evidence either way would be inventing a finding.

**Is infinite scroll bad for AI visibility?**

The infinite scroll itself is not the problem; an infinite scroll that is the only way the content exists is. Google's guidance asks for a persistent unique URL per chunk, stable content at that URL, sequential links between chunks and a History API update as the reader moves, which together make the scroll a presentation layer over addressable pages. A feed built that way loses nothing. A feed with no addressable chunks offers a crawler nothing to request beyond the first screen.

**Does Lantad's scanner scroll, and how far?**

It scrolls three viewports. The depth is a setting named autoScrollViewports in core/src/config.ts, chosen to fit a scan budget rather than derived from any measurement of how far pages extend. After the final pass the scanner compares the last two document height samples, and if the document was still growing it attaches a note stating that text below the last scrolled viewport may be undercounted. The note is an admission that the number is a floor, not a claim that the page was read in full.

---

Lantad measures whether AI crawlers can actually read a page: it fetches as a non-rendering
crawler, renders as a browser, and reports the gap. Free scan, one URL, no signup.

Method and weights: https://lantad.co/methodology | All pages as markdown: https://lantad.co/md | Crawler policy: https://lantad.co/bot
