Skip to content
PreferiumJoin the waitlist

Technical SEOAI Search

AI crawlers found zero of the pages linked only by JavaScript

A 41-day logged experiment split one site between hard-coded HTML links and JavaScript-injected ones. GPTBot, ClaudeBot, Amazonbot and Meta’s crawler reached none of the JavaScript side. Googlebot reached 2%.

A line of four-legged robots halts at the edge of a stone ledge above a foggy chasm, while a rope bridge spans the gap only on the far side, out of reach.
Jump to a section

In a 41-day experiment on one directory site, several crawlers reached pages linked in the initial HTML but none of the deeper pages linked only through JavaScript. The study is a useful test case for navigation, with limits on what it tells us about indexing or AI citations.

The difference in the page response

A crawler is a program that reads web pages the way a very fast, very literal person would — it opens a page, notes the links on it, and goes to those next. Links are one way to discover pages; sitemaps and other discovery routes can also matter.

The distinction is when the link becomes available:

  • In the initial HTML: the server sends the link with the page. A crawler can follow it without running a script.
  • Added by JavaScript: the browser creates the link after the page arrives. A crawler must run that script to see it.

A framework can use either approach, depending on how the site is configured and rendered.

A browser with JavaScript enabled can run that program. A crawler only does if somebody built it to, and it’s expensive — you have to launch what amounts to a whole browser for every page. Do not assume that a fetcher renders it.

The experiment

Vinicius Stanula, Associate Director of SEO at LOCOMOTIVE, took a Brazilian business directory of roughly 2,400 pages and cut its navigation in half. Of the 21 sections in the test hierarchy, 11 kept hard-coded HTML links and 10 had their links injected by JavaScript instead.

Everything else that could give a crawler a back door was switched off: no sitemap, no breadcrumbs, no internal panels pointing at the deeper pages. Then he logged every single bot request for 41 days — path, user agent, IP, timestamp — and let the crawlers do whatever they were going to do.

The write-up is on Search Engine Land, published 19 August.

The setup deliberately restricted alternative discovery routes. When a page is missing from an AI answer you can rarely tell whether the crawler couldn’t find it or found it and didn’t care. Here there was only one route in.

The numbers

For four crawlers, the difference was clear. These are counts of deeper pages reached in the two groups:

Crawler Linked in HTML Linked only by JavaScript
GPTBot 759 0
ClaudeBot 759 0
Amazonbot 735 0
Meta’s crawler 537 0

GPTBot fetched all 759 pages in the HTML group on day one; ClaudeBot did so a day later. Both visited the JavaScript group’s section pages but reached none of its deeper pages. Bingbot reached three JavaScript-linked pages, about 1% of that group.

Google’s crawlers behaved differently. GoogleOther, used for research and product work, reached 48% of the JavaScript group. Googlebot, which feeds Google Search, reached 2% of that group and 5% of the HTML group.

These logs establish which pages were fetched in this setup. They do not explain the providers’ reasons or show which pages later appeared in search results or AI answers.

An earlier source provides additional context. Vercel’s crawler study back in December 2024 found the same thing from the other direction: no major AI crawler renders JavaScript.

GPTBot and ClaudeBot do download JavaScript files — Claude in nearly a quarter of its requests — they just never run them. That observation comes from a different dataset and should be read with its date and scope attached.

Getting it back is slower than losing it

Stanula then converted the JavaScript links to plain HTML and kept logging. Recovery was not uniform. GPTBot swept 250 previously unreachable pages within 48 hours. Bingbot worked through its backlog over about a week. ClaudeBot mostly carried on recrawling pages it already knew about, and Googlebot had barely moved by day 41.

So the cost of the mistake isn’t symmetrical with the cost of the fix. Restoring links did not produce the same recrawl timing for every crawler in the test.

What to do about it

Turn JavaScript off and load a category page and a deep product or article page. Check whether navigation, category links and pagination still work. This helps reveal what a fetcher receives without rendering scripts; the next step is to inspect the server response.

Then check what the server actually sends. curl the URL and search the response for a link you know should be there. If the link is absent, a fetcher that does not render JavaScript cannot follow it from that response.

Where links are missing, render the navigation on the server. Focus on the links needed to discover the site’s pages; this does not require replacing the whole application.

Google’s guidance for generative AI features also keeps the ordinary search requirements in place: a page must be indexed and eligible to appear with a snippet. Readable navigation helps discovery, but does not guarantee indexing or a citation.

Want this running under your brand?Resell Preferium AI Edge with your brand, Stripe, packages and prices. Agency registration opens by invitation from the waitlist.Talk to usJoin the waitlistHow white label works

Privacy choices

Choose which optional technologies Preferium AS may use. All of them are off until you choose.

Analytics: Google Analytics 4 counts page views. Google may receive the page address, referrer, network address, browser and device details, and online identifiers. Browser storage: _ga, _ga_*: Up to 730 days. Renewed on activity. The browser may shorten the storage period.

Provider: Google Ireland Limited. Google may transfer data to the United States.

See the cookie notice, the privacy notice and theterms.

Necessary technologies Used for site functions

Preferium AS and Cloudflare deliver the site and protect forms against abuse. A local preference remembers if you pause animation. When optional tracking is available, the site can also remember your documented privacy choices.

Consent receipt
Provider: Preferium AS. HttpOnly receipt that documents and retrieves your consent choice. Name in the browser: __Host-preferium_consent. Storage period: The receipt is valid for up to 180 days without rolling renewal.
Local privacy choices and pending rejections
Provider: Preferium AS. Local storage of privacy choices and pending rejections. The entry alone can never allow optional technologies; a valid server receipt is required. Name in the browser: preferium-consent-v2. Storage period: Until the entry is overwritten or the browser site data is cleared. No automatic timed deletion is configured.
Privacy choice synchronization between tabs
Provider: Preferium AS. The latest message that synchronizes privacy choices and pending rejections between tabs. The message can only close optional technologies and trigger a new server check. Name in the browser: preferium-consent-sync-v1. Storage period: Until the entry is overwritten or the browser site data is cleared. No automatic timed deletion is configured.
Motion pause preference
Provider: Preferium AS. Session storage restores the requested accessibility preference between pages in this tab. Nothing is sent to a server. Name in the browser: preferium-motion-paused. Storage period: Until this browser tab session ends.
Cloudflare Turnstile
Provider: Cloudflare. Abuse protection that loads only on forms where Turnstile is necessary. Storage period: Short-lived control value tied to a form submission.
Analytics

Helps us understand how the site is used, when you consent.

Provider: Google Ireland Limited. The data may include the page address, referrer, network address, browser/device, online identifiers and usage events.

_ga, _ga_*
Processes site usage for aggregated analytics after specific consent. Storage period: Up to 730 days. Renewed on activity. The browser may shorten the storage period.

You can withdraw your choice via Privacy choices. That stops further optional loading but does not recall data already sent to Google. We attempt to delete known first-party values; the browser may prevent deletion of third-party values.

How Google uses and is responsible for data · How Google uses information from partner sites · Google privacy policy