
Element Code: PE-019
What this check actually flags
This check compares the raw HTML your server sends with the DOM after JavaScript has executed. When the meaningful stuff, body copy, product data, headings, internal links, titles, canonicals, only shows up in the rendered version, the page is flagged. The initial response is a shell: a root div, a bundle of script tags, and a promise that content will arrive once the browser does its part.
That architecture is fine for a logged-in dashboard. On a public page that needs to rank, it means every system consuming your site has to run a full browser to see anything, and most of them simply do not.
How Google actually handles JavaScript
Google can render JavaScript, and it is genuinely good at it. Googlebot renders pages with an evergreen version of Chromium, so modern JS features are not the problem. The catch is the pipeline: crawling and rendering are separate steps. Googlebot fetches your HTML first, and pages needing JS go into a render queue before the Web Rendering Service executes them. Google's Martin Splitt has said most pages get rendered within minutes, but it is still a deferred second pass that can fail on timeouts, blocked resources, or script errors, and when rendering fails, whatever only existed client-side simply does not exist.
Two hard limits people keep forgetting. First, Googlebot does not click, so content fetched only after a tap on "Load more" or a tab that pulls data on demand is never seen. Second, links that are not real anchor elements with an href, the classic div-with-onclick navigation, are not reliably followed, which quietly starves whole sections of a site of internal links.
Google is the best case. Everyone else is worse
Optimizing JS rendering for Google alone made sense in 2019. It does not anymore, because the crawlers that increasingly decide whether you get cited do not render at all. Research published by Vercel and MERJ in late 2024 tested the major AI crawlers and found that GPTBot, ClaudeBot and PerplexityBot fetch the raw HTML and do not execute JavaScript. If your product specs, article body or pricing only materialize client-side, you are handing AI assistants a blank page while your server-rendered competitor gets quoted. Social link previews and smaller search engines behave the same way. Bing does render JavaScript, but nobody outside Redmond will promise you the same coverage and patience Google shows.
How to detect it
- Disable JavaScript and reload: in Chrome DevTools, hit the command menu, type "Disable JavaScript", reload the page. Whatever vanished is your exposure. Thirty seconds, no tooling budget required.
- View source versus rendered DOM: compare the actual server response (view-source or curl) with the Elements panel. If the body copy is in the second and not the first, it is JS-loaded.
- Search Console URL Inspection: run a live test and open the rendered HTML and screenshot. This shows what Googlebot itself produced, including anything that failed to render.
- Screaming Frog in JavaScript rendering mode: enable rendering under Config, then use the JavaScript tab, which flags pages where word counts and links differ between raw and rendered HTML. This is how you find the problem at template scale instead of page by page.
How to fix it, step by step
- Inventory the damage. List what is JS-only: main copy, titles, meta robots, canonicals, structured data, internal links, product data. Meta signals living only in the rendered DOM are a special kind of footgun, since a client-side canonical can flip after the HTML one was already processed.
- Pick a rendering strategy per template. Static generation for stable marketing and blog pages, server-side rendering for pages that change per request, and keep pure client-side rendering for authenticated views that should not be indexed anyway.
- Use the framework's server mode. Next.js, Nuxt and SvelteKit all ship server rendering with client hydration, so you keep the interactive feel while the first HTML response carries the full content.
- Make navigation real. Every crawlable destination gets a genuine anchor with an href. Router libraries support this; teams just forget to use it.
- Do not block the machinery. If some content must stay client-rendered, never block the JS, CSS or API endpoints it needs in robots.txt, or Google's renderer produces the same blank shell as everyone else.
- Retest. URL Inspection on the fixed templates, a fresh Screaming Frog rendering crawl, and a diff of raw HTML before and after. The win condition: content visible with JavaScript off.
| Strategy | Content in first HTML response | Crawler safety | Best for |
|---|---|---|---|
| Static generation (SSG) | Yes | Safest | Blogs, docs, marketing pages |
| Server-side rendering (SSR) | Yes | Safe | Frequently changing or personalized pages |
| SSR plus hydration (hybrid) | Yes | Safe | Interactive product experiences |
| Client-side rendering (CSR) | No | Risky | Logged-in app views only |
| Prerendering for bots (dynamic rendering) | Bots only | Workaround | Legacy SPAs you cannot rebuild yet |
On that last row: Google's own documentation now describes dynamic rendering as a workaround rather than a recommended long-term solution. It buys time for an old single-page app; it is not an architecture to build toward in 2026.
What good looks like
Load any public page with JavaScript disabled and the headline, body content, and navigation are all there. Titles, canonicals and structured data live in the server response, not in a script's side effects. The Screaming Frog JavaScript report shows near-zero difference between raw and rendered word counts on indexable templates. JS still runs, the site still feels like an app; it just stops being the only place your content exists.
- Server-render primary content, titles, canonicals and structured data
- Use real anchor tags with href for every crawlable link
- Test templates with JavaScript disabled after each release
- Check the rendered HTML in URL Inspection, not just the browser
- Treat client-side JS as an enhancement layer
- Don't fetch body copy from a client-side API on public pages
- Don't hide content behind clicks that trigger a network request
- Don't block JS, CSS or API routes in robots.txt on rendered pages
- Don't treat dynamic rendering as a permanent architecture
- Don't assume Google rendering it means every bot sees it
FAQ
Can Google index JavaScript content at all?
Do AI crawlers like GPTBot run JavaScript?
Is content in hidden tabs or accordions a problem?
We prerender for bots with a service. Good enough?
How do I see exactly what Googlebot saw?
Suspect your framework is hiding content from crawlers?
Rendering problems are invisible in a browser and brutal in the index. My advanced SEO audit includes a raw-versus-rendered comparison across your templates, so you know exactly what every crawler can and cannot see.
Claude Vincent is a technical SEO consultant focused on crawlability, rendering, and AI-search visibility. He writes the field guides and case studies at SEO ProCheck, with a bias toward the durable, unglamorous work that decides whether search engines and AI answer engines can actually read and cite a site.
About SEO ProCheck
Technical SEO consulting and GEO strategy with 20 years of enterprise experience. Case studies, resources, and tools for search and AI visibility.
Work With Me
Technical SEO audits, GEO strategy, site migrations, and international SEO. Hourly consulting for teams who need hands-on support, not just reports.







