JS-only content: invisible to non-JS crawlers and AI
If your content only renders with JavaScript, non-JS crawlers and AI agents may see an empty shell. Find JS-only pages and learn how to fix rendering.
What it means
The raw HTML this URL returns is an almost-empty shell — a few script tags, a <div id="root">, maybe a loading spinner — and effectively none of the visible text, headings, or links exist until JavaScript builds the page in the browser. This is the classic single-page-app response: the server ships an app bundle, not a document. It is a stronger failure than rendering.js_dependent, where the raw HTML already carries most of the content and JS only augments it; here the pre-render HTML has essentially nothing to index.
Why it matters
Google renders JavaScript, but not for free and not instantly: a JS-only page goes into a render queue that can lag hours to days behind the initial crawl, so your content is discovered late and re-crawled less often. Any render failure — a script 404, a timeout, a blocked CDN, an unhandled exception — leaves Googlebot with the empty shell and nothing to index. Everything downstream of the shell degrades too: internal links that only exist post-render may never be followed (orphaning pages), and the crawlers that do not execute JavaScript at all — Bing to a large degree, and most AI answer engines and social-preview bots (GPTBot, PerplexityBot, Facebook, Slack) — see a blank page, so you are absent from AI citations and link previews.
How to fix it
- Compare the two views: fetch the URL with
curl -A Googlebot <url>(raw HTML) and check it against Search Console URL Inspection → Rendered HTML. If the raw response has no headline or body copy, this rule is correct. - Move primary content into the initial HTML with server-side rendering (SSR) or static generation (SSG) — Next.js/Nuxt server components, Astro, or a prerender step. The goal is that the first byte already contains the H1, body text, main links, and meta tags.
- If a full SSR migration is not feasible short-term, add prerendering for crawlers (e.g. Prerender.io or a headless-Chrome cache) so bots receive a fully-rendered snapshot while users still get the SPA.
- Use hydration rather than client-only rendering: render the HTML on the server, then let JavaScript attach interactivity on top of the existing markup instead of creating it from scratch.
- Never gate content behind a click, scroll, or authentication for URLs you want indexed — Googlebot does not interact with the page.
- After deploying, re-inspect the URL and confirm the content now appears in the raw HTML, not only in the rendered output.
When it's not a problem
It is not a problem when the page is deliberately kept out of search — an app dashboard, an account area, or any authenticated view behind a login — since there is no organic content to index anyway. It is also acceptable for a page that is reliably rendered and whose content is fully represented on another indexable URL. If the shell is intentional, keep those routes out of your sitemap and let the canonical, indexable pages carry the SEO weight.
How common is it?
807 audited sites in our corpus currently show this issue. The breakdowns below show which platforms, gatekeepers, verticals and countries are most exposed.
Audit your own site — free
157 checks, internal PageRank, render-diff. No signup, results in ~30s.