---
title: "Fix: AI Crawlers Don't Render JavaScript Content"
description: "Do AI crawlers render JavaScript? Most do not. See how to test your page with curl and move its main content into the first HTML response."
url: https://seenlens.com/fixes/content-needs-javascript
last_updated: 2026-11-06
---

# Do AI crawlers render JavaScript? How to fix a page that needs it

Most AI crawlers do not render JavaScript. If your text appears only after scripts run, they see an empty page. The cause is client side rendering. The fix is to send the main content in the first HTML response, with server rendering or a static build. A framework change can take a few days, and a small fix on one page can take an hour.

By SeenLens. Last updated: 2026-11-06

## Do AI crawlers render JavaScript?

Vercel analysed crawler traffic on nextjs.org and other sites and published the result on 2024-12-17. It found that GPTBot, ClaudeBot and PerplexityBot did not render JavaScript. Applebot and Gemini did. ChatGPT and Claude fetched JavaScript files (11.50% and 23.84% of their requests) but did not run them. This is one vendor's traffic data from late 2024, so test your own page.

Google works differently. Googlebot queues pages for rendering and runs them in a headless Chromium. Google still calls server side rendering or prerendering a great idea, and notes that not all bots can run JavaScript.

## server-rendered: is the main content in the raw HTML?

SeenLensBot reads the raw HTML response without running scripts. It removes script, style, noscript, template and svg elements and counts the visible words.

| Result | Words in the raw HTML |
| --- | --- |
| Fail | Fewer than 50 words and a JavaScript shell marker (an empty `root`, `app`, `__next` or `__nuxt` container, or an enable JavaScript message) |
| Warn | Fewer than 150 words |
| Pass | 150 words or more |

## render-needed: did the scanner need a browser?

The scanner decides whether the raw HTML is a JavaScript shell. A page counts as a shell when it has a known hydration marker and under 400 characters of visible text, when it carries builder markers with little text, or when its body holds under 100 characters. A shell makes the scanner load the page once in a headless browser.

- **Fail:** the raw HTML was a shell, and the content came only from the browser render.
- **Warn:** the raw HTML looks like a shell, and the browser render failed, so the scan used the raw HTML.
- **Pass:** the content was present in the raw HTML.

If a bot wall answers the request, both checks report "not tested" until you fix the [firewall block](https://seenlens.com/fixes/ai-crawlers-blocked-by-waf).

## How to confirm the problem

Pick a sentence from the visible page text and search the raw HTML for it. Zero matches means the text is added by JavaScript.

```text
curl -sL https://example.com/your-page | grep -c "a sentence from your page"
```

In Chrome, `view-source:` followed by the URL shows the same raw HTML. The embedded scan shows the result of both checks.

## How to fix it

The goal is the same on every platform: the headline, the body text and the links must be in the first response.

### Next.js (App Router)

Server Components render on the server. Keep the page a Server Component, fetch data in it and move only interactive widgets into files that start with `"use client"`. Next.js adds the title and description tags to the initial HTML for prerenderable pages (docs updated 2026-08-19).

```text
// app/pricing/page.tsx (a Server Component: no "use client")
export default async function Page() {
  const plans = await fetch("https://api.example.com/plans").then((r) => r.json());
  return (
    <main>
      <h1>Pricing</h1>
      <ul>{plans.map((x: { id: string; name: string }) => <li key={x.id}>{x.name}</li>)}</ul>
    </main>
  );
}
```

### Single page apps (React, Vue, Svelte with a client router)

Move to a framework mode that prerenders or server renders each route, for example Next.js or Nuxt. A build time prerender of the public pages works for sites with stable content. Do not fetch the main text inside `useEffect` or after the first paint.

### WordPress, Shopify and website builders

These platforms render pages on the server. The problem usually comes from one widget, such as a review app, a tab component or a page builder block that loads text with JavaScript. Find it with the curl test and replace it with a server rendered version.

## How to verify the fix

1. Run the curl test again. The sentence must appear.
2. Run the SeenLens scan. Both checks should pass.
3. Check that your title, description and canonical tags are also in the raw HTML.

[Run the free SeenLens scan on your page](https://seenlens.com/)

## When can you ignore it?

Ignore it for pages behind a login, for dashboards and for tools. Crawlers do not need to read them. Do not ignore it on pages you want AI search to cite.

## Related checks

- [Crawlers cannot load the page](https://seenlens.com/fixes/ai-crawlers-cannot-load-page)
- [Page title missing](https://seenlens.com/fixes/page-title-missing)
- [Missing H1 tag](https://seenlens.com/fixes/h1-heading-missing)
- [Is my website visible to AI?](https://seenlens.com/guides/is-my-website-visible-to-ai)

## Sources

- [Vercel: The rise of the AI crawler](https://vercel.com/blog/the-rise-of-the-ai-crawler) (JavaScript rendering by AI crawlers, published 2024-12-17, vendor data from nextjs.org)
- [Google Search Central: JavaScript SEO basics](https://developers.google.com/search/docs/crawling-indexing/javascript/javascript-seo-basics) (Googlebot rendering, server side rendering advice, checked 2026-11-06)
- [Next.js: generateMetadata](https://nextjs.org/docs/app/api-reference/functions/generate-metadata) (metadata in the initial HTML, updated 2026-08-19)
