Docket / Fix it / JavaScript SEO audit

How to run a JavaScript SEO audit

A JavaScript SEO audit answers one question: is the thing you wrote in the HTML your server sends, or does it only exist after JavaScript runs? Everything else — which framework, which rendering mode, whose crawler — follows from that answer, and you can get it in about ten minutes.

Why the answer is not obvious from looking at the page

Open the page in a browser and it looks complete, because your browser ran the JavaScript. View source and you may see something entirely different. Those two views disagree on plenty of real sites, and the disagreement is invisible until you go looking for it.

It matters because the two audiences behave differently. Google renders JavaScript, on a delay and with no guarantee about when. The AI crawlers that increasingly decide whether you get quoted in an answer mostly do not render at all — to them, the page is whatever the server sent. So a page can rank adequately and be invisible to the systems people now ask instead of searching. AI search visibility is a separate surface with a separate failure mode.

Step 1: read the HTML your server actually sends

Not the rendered DOM. The bytes.

curl -sS https://example.com/your-page/ | wc -c

Then look at the body text inside those bytes, not the byte count — a big HTML payload with almost nothing readable in it is exactly the shape you are hunting. A page can be 200 KB of markup and carry forty words a reader would recognise.

Step 2: render the same URL and compare

The audit is the comparison, not either number on its own. In Docket:

docket-render https://example.com/your-page/ --timeout 45 --settle 4

It returns the rendered HTML with the link count, the text length and the script sources, so you can put the two side by side. Any headless browser does the same job; what matters is that you measure both views of the same URL in the same session, because comparing today's render against last week's source tells you about the week, not the page.

Step 3: read the gap, and know which gap you have

There are three outcomes and they have different remedies.

The two views agree. The page is server-rendered. There is no JavaScript SEO problem here and you can stop — resist the urge to find one.

The HTML is essentially empty. A shell, a mount point and a script tag. Every crawler that does not render sees nothing, and the fix is server-side rendering or prerendering. This is the case most articles describe, and it is the easier one, because it is obvious the moment you look.

The chrome is server-rendered and the body is not. This is the one that hides. The navigation, header and footer arrive in the HTML — so the page is plainly not an empty shell — while the article itself is fetched after hydration. Measured on one site on 2026-09-09, 5 pages returned 27, 49, 52, 59 and 67 words of main text as served, and 607, 318, 224, 666 and 671 once rendered. The pages were not thin. The served HTML was. That is 5 pages on one site — an existence proof that the shape occurs and is large when it does, not a claim about how common it is.

Docket shipped a change for exactly this in v1.3.61: where a page carries a client-side framework's hydration marker, a word count is now labelled as a count of the HTML as served, because a tool that reports "almost no content" about a page carrying six hundred words is telling you something false in a confident voice.

Step 4: check what a non-rendering crawler is allowed to fetch

Rendering is only half of it. A crawler that renders nothing still has to be let in, and the refusal usually happens somewhere your robots.txt never sees — a bot rule at the CDN, returning 403 to a user-agent the site owner believes is welcome. Send the same request twice, once with the crawler's user-agent and once with an ordinary browser's, and compare: if only one is refused, the rule is about the crawler. Fixing AI crawler access covers the robots.txt side of the same question.

Step 5: confirm what was actually fetched

A render tells you what a browser can build. It does not tell you what any crawler did. For that you need the server's own record — log file analysis — which is the only view that distinguishes "Google could reach this" from "Google fetched this". The two disagree constantly, and on a JavaScript-heavy site they disagree more.

What this audit does not tell you

It does not tell you whether Google rendered your page, or when, or what it saw — nobody outside Google can measure that, and a tool that implies otherwise is selling you a model as a measurement. It tells you what the two views contain, which is the part you control.

It also will not tell you that a slow render is the reason you are not ranking. Rendering delay is real and it is frequently blamed for outcomes it did not cause. Measure the gap, fix the gap, and judge the result against what you recorded before you started.

Doing it across a whole site

The steps above are per-URL, which is fine for a spot check and useless for a site with a thousand pages. Docket runs the comparison across the crawl and reports the pages where the two views disagree, alongside the rest of a technical SEO audit97 checks across 13 areas, on your machine, with no crawl credits. If you would rather see how it compares to the tools you already know, there is Docket vs Screaming Frog and Docket vs Ahrefs Site Audit.

Whatever you use, the discipline is the same: two views of the same URL, measured in the same session, and a decision about which of the three gaps you are looking at before you change anything.

Download Docket

Common questions

What is a JavaScript SEO audit?

A comparison of two views of the same URL: the HTML the server returns, and the page after JavaScript has run. Where they disagree, some crawlers see less than your visitors do. Everything else in the audit follows from the size and shape of that gap.

Does Google render JavaScript?

Yes, on a delay and with no guarantee about when. That is not the same as saying it makes no difference: the render is a second pass, and the AI crawlers that increasingly decide whether you are quoted mostly do not render at all. A page that only exists after JavaScript is invisible to them.

My page looks fine in the browser. Is that enough?

No, and it is the most common reason this problem goes unnoticed. The browser ran the JavaScript before you looked. Use view-source or curl to see what the server sent, which is what a non-rendering crawler gets.

The HTML has my navigation and footer but not the article. Is that a shell?

Not a shell, and it is the case that hides. An empty shell is obvious; a page whose chrome is server-rendered looks server-rendered at a glance while the body arrives after hydration. Compare the MAIN content of the two views, not the page as a whole, or the navigation will mask the gap.

Can a tool tell me what Googlebot rendered?

No. Nobody outside Google can measure what Google rendered or when. A tool can tell you what your server sent and what a browser builds from it; anything beyond that is a model presented as a measurement.