Skip to content
Sign in

What crawlers see on a JavaScript-rendered site

If your content is built in the browser, crawlers that do not run JavaScript see an empty page. Here is how to test it in two minutes and which fix fits your site.

DeskSEO editorial team · · 5 min read

A page can look complete in a browser and be almost empty to a crawler. The difference is where the text comes from. If the server sends finished HTML, every crawler sees the content on the first request. If the server sends a shell with a <div id="root"></div> and a JavaScript bundle that builds the page in the browser, only crawlers that run JavaScript will ever see the words. Many do not.

Who runs JavaScript and who does not

Google: two waves

Googlebot fetches the raw HTML first and can index what is in it straight away. Pages that need JavaScript are queued for rendering in a headless Chromium, and the rendered result is processed after that. Google documents this as crawl, render, index. In practice the render step usually follows quickly, but it is a separate queue: links that only exist after rendering are discovered later, and anything that fails during rendering (a blocked script, an API call that times out, a consent wall) means Google indexes whatever the shell contained.

Bing

Bing also renders JavaScript, but Microsoft's own guidance recommends server-side or pre-rendered content for important pages, especially on large sites.

AI crawlers

For the crawlers behind AI assistants the picture is less clear, and vendors document little about rendering. Independent log analyses published in 2024–2025 found that several major AI crawlers fetched JavaScript files without executing them, so they worked from the raw HTML. That can change at any time, and it is not confirmed for every vendor. The safe assumption is: if the text is not in the HTML response, an AI crawler probably does not see it. The same applies to link-preview bots (Slack, LinkedIn, messaging apps) and most SEO tools.

Test it in two minutes

  1. View source, not Inspect. In a desktop browser open view-source:https://example.com/ (or press Ctrl+U / Cmd+Option+U). This shows the HTML the server sent. The Elements panel in developer tools shows the page after JavaScript ran, which is what you do not want to look at here.
  2. Search the source for a sentence from the middle of the page, such as a product description or the second paragraph of an article. If it is not there, crawlers that do not render cannot read it.
  3. Check the essentials in the source: the <title>, meta description, canonical, the H1, internal links as real <a href> elements, and JSON-LD. Single-page apps often set these from JavaScript, which means the raw HTML carries a generic title on every URL.
  4. Use a tool that does not render. The free SEO checker reads the raw HTML exactly as a non-rendering crawler would. Its "machine-readable words" count and the AI bot checker's "text readable without JavaScript" figure both come from the HTML response with scripts and styles stripped.
  5. Compare with Google's view. The URL Inspection tool in Search Console has a "View crawled page" option that shows the HTML Google rendered. If your source is empty but Google's rendered HTML is full, Google is fine and other crawlers are not.

A homepage below 300 machine-readable words is flagged by DeskSEO as thin content. On a JavaScript site that number is often near zero, which is the clearest sign the problem is rendering, not writing.

The fixes, from most to least robust

ApproachWhat it meansGood fit
Static generation (SSG)Pages are built into HTML files at deploy timeMarketing sites, blogs, documentation, catalogues that change daily or less
Server-side rendering (SSR)The server builds the HTML on each request, then JavaScript takes over in the browserShops, listings, anything personalised or fast-changing
Hybrid / incrementalStatic pages regenerated in the background on a schedule or on changeLarge catalogues
Pre-rendering serviceA service renders pages and serves the HTML snapshot to botsLegacy single-page apps you cannot rebuild soon

Most current frameworks support the first three directly: Next.js and Remix for React, Nuxt for Vue, SvelteKit, Astro and Angular's server rendering. Moving an existing client-only app to one of these modes is usually less work than it sounds, because components stay the same; the change is in routing and data loading.

Pre-rendering for bots only (Google calls it dynamic rendering) is a stop-gap. Google accepts it as long as bots and users get the same content, but now describes it as a workaround rather than a recommended solution, and it adds another moving part that breaks silently: when the snapshot service fails, bots get the empty shell and nothing alerts you.

Mistakes that hide content even on rendered sites

  • Links as click handlers. <div onclick="go('/pricing')"> or <a href="#"> with JavaScript navigation gives crawlers nothing to follow. Use <a href="/pricing">; the router can still intercept the click.
  • Content behind interaction. Text that loads only after a click, a scroll event or a tab switch is not reliably seen. Put it in the HTML and hide it with CSS if needed; collapsed content in the source is still read.
  • Blocked resources. If robots.txt disallows /static/ or /api/, Google cannot run the scripts or fetch the data it needs to render.
  • Hash routes. URLs like /#/products/42 are one URL to a crawler. Use real paths.
  • Metadata set in the browser. A title or canonical changed by JavaScript may differ from the raw HTML. Google can pick up the rendered version; other crawlers and link previews use the raw one. Render metadata on the server.
  • Soft 404s. A single-page app that answers every path with status 200 and an "item not found" message produces thousands of indexable empty pages. Return a real 404 status from the server.

What to prioritise

Not every page needs server rendering. Logged-in dashboards, carts and account areas can stay client-side; they should not be indexed anyway. Start with the pages people search for: the homepage, category and product pages, articles, pricing, and contact. Once those return full HTML, re-run the SEO checker and watch the word count, H1 and canonical items move. For crawler access rules, read allowing or blocking AI crawlers in robots.txt, and for the metadata that should be in that HTML, see titles and meta descriptions.

Questions

Google renders JavaScript, so why does it matter?

Rendering is a separate, later step that can fail, and links found only after rendering are discovered later. Other search engines, AI crawlers, link-preview bots and most SEO tools read only the raw HTML.

How do I know if my site depends on JavaScript for content?

Open view-source: on the page and search for a sentence from the middle of the content. If it is missing from the source, the text is built by JavaScript.

Is dynamic rendering (serving bots a pre-rendered snapshot) cloaking?

Not if bots and users get the same content. It is a workaround, though: when the snapshot service fails, bots silently receive the empty shell.

Keep reading