Auditing JavaScript Rendering with Screaming Frog

URL Inspection tells you the truth about one URL; auditing a whole site needs a crawler that renders JavaScript across every template. Screaming Frog’s JavaScript rendering mode executes each page in headless Chromium and stores the rendered DOM, so you can find the product pages, filtered listings, or paginated routes that render empty while the homepage looks fine. This is the at-scale stage of the SPA audit workflow.

The rendering-mode switch decides whether a Screaming Frog crawl is meaningful In Text Only mode the crawler reports every CSR route as an empty shell; switching to JavaScript renders each page in headless Chromium, stores the DOM, and lets you triage empty or metadata-missing templates. One config switch decides the whole audit Rendering mode Config → Spider Text Only JavaScript Empty shell for every route audit is meaningless — dead end Headless Chromium runs bundle Rendered DOM stored per URL Triage failures word count ≈ 0, missing title/canonical
Text Only reports a false all-empty result; only JavaScript mode renders the DOM you can actually triage at scale.

Step-by-step fix

  1. Enable JavaScript rendering. In Configuration → Spider → Rendering, switch to JavaScript. Without this, the crawl reports the empty shell for every CSR route.

    ❌ Rendering: Text Only      → every CSR page reported as empty/thin
    ✅ Rendering: JavaScript     → crawler executes the bundle, captures rendered DOM
  2. Set an adequate render timeout. Give pages enough time to resolve data, but note that a page needing many seconds to render is itself an SEO problem worth flagging.

  3. Store and compare raw vs rendered. Enable storing both so you can see which content exists only after JavaScript — that content is exactly what depends on the render queue.

  4. Filter for failures. After the crawl, sort by rendered word count, missing <title>, and missing canonical to surface broken templates.

    Post-crawl triage:
    - Rendered word count ≈ 0        → page renders empty (render failure)
    - Title/H1 present in raw? No     → metadata depends on JS (audit the head)
    - Canonical missing after render  → duplicate-content risk
  5. Confirm the worst offenders in Search Console so you act on Googlebot’s actual behavior, not just the crawler’s approximation.

Storing both the raw HTML and the rendered DOM for each URL turns the crawl into a diff: whatever content appears only on the rendered side is exactly what depends on the render queue and is at risk if the render fails.

The same route stored as raw HTML versus rendered DOM Side by side, the raw HTML holds only an empty root container while the rendered DOM captured after JavaScript holds the heading and body copy the crawler can index. Store both — the gap is the content that depends on the render Raw HTML 0 words <div id="root"> </div> empty shell render Rendered DOM 812 words heading and body copy present
The raw-versus-rendered diff makes the render's contribution visible: an empty shell becomes 812 indexable words only after JavaScript runs.

Validation

  • Rendered word count is non-trivial for every content template.
  • Raw vs rendered diff shows expected content appearing after rendering, not disappearing.
  • No template reports a missing rendered <title> or canonical.
  • Sampled URLs confirmed in GSC URL Inspection match the crawl findings.

Sorting the crawl by rendered word count ascending is the single fastest triage move: the empty and thin renders float to the top, below a rough thin-content threshold, while healthy templates sit well above it.

Sorting rendered word count ascending floats empty pages to the top A bar chart of rendered word count per crawled URL sorted ascending, with a threshold line below which pages count as empty or thin render failures and above which pages are healthy. Rendered word count per URL (sorted ascending) thin threshold 0 0 12 340 610 820 render failures healthy templates
An ascending word-count sort surfaces the render failures instantly: the three bars under the thin threshold are the pages that rendered empty.

Reference

Screaming Frog config for a CSR audit:
- Spider → Rendering: JavaScript
- Rendering → AJAX timeout: raise until renders complete
- Spider → Extraction: store Rendered HTML
- Bulk Export → Response Codes + Page Titles + Canonicals
- Sort: Word Count (rendered) ascending → empty pages float to top
The Screaming Frog settings that make a CSR crawl valid A settings checklist: JavaScript rendering is the decisive switch, then a raised AJAX timeout, storing the rendered HTML, exporting response codes with titles and canonicals, and sorting rendered word count ascending to float empty pages up. The config checklist for a CSR audit Rendering: JavaScript — the switch that makes the crawl real AJAX timeout: raised until renders complete Store: raw HTML + rendered HTML for the diff Bulk export: response codes, titles, canonicals Sort: rendered word count ascending — empty pages float up
The rendering-mode toggle is the decisive setting; the remaining options store, export, and sort the crawl so empty templates surface for triage.

Frequently Asked Questions

Why does my crawler report every page as empty? A crawler in default mode fetches only the initial HTML, which for a CSR app is an empty shell. Enable JavaScript rendering so the crawler executes the bundle and captures the rendered DOM, the way Googlebot’s second wave does.

Does a JS-rendering crawl match what Googlebot sees? It is a close approximation — both render in headless Chromium — but Googlebot applies its own timeout and resource budget. Use the crawl to find broken templates at scale, then confirm specific URLs in Search Console URL Inspection for the authoritative view.

← Back to SEO Audit Workflows for Client-Side Apps