Content that needs JavaScript: invisible to raw-HTML agents
Most of a page's text arriving only after JavaScript runs. squirrel compares the raw HTML against the rendered DOM and reports the gap.
What JavaScript-gated content is
Many crawlers and most AI agents fetch a URL and read the bytes the server sent. They do not run a browser. Content a framework injects on the client is therefore absent from what they see, even though it is on screen for a person.
Server rendering or static generation puts the text in the initial HTML, which is what fixes this. Interactive parts can stay on the client; the question is only whether the content an agent needs to understand the page is in the response body. A page whose raw HTML is an empty shell reads to an agent as a page with nothing on it.
What squirrel checks
The rule compares the raw crawl HTML with a browser-rendered copy of the same page, extracting words from both with the same pipeline so the two counts are comparable. Rendering is a cloud service, so the check needs a cloud audit. It emits one check:
content-without-js, skipped with the messageRaw-vs-rendered content comparison skippedin two cases: the crawl itself was browser-rendered, which would make the comparison self-identical, or the render service was not available for the audit. When the service ran but returned no HTML for this page the message isNo rendered HTML returned for this pageinstead. The skip reason names which.content-without-js, at info status with the message~N% of this page's content (M words) appears only after JavaScript runs — agents that read raw HTML won't see it.content-without-js, passing with the messageRaw HTML already contains the bulk of the rendered content.
The gap is reported only when all three of the following hold: the rendered page has at least 200 words, at least 100 of them are missing from the raw HTML, and the raw HTML covers no more than 60% of the rendered word count. Coverage is clamped to 100%, because raw can legitimately exceed rendered when a <noscript> block is stripped during render. The rule is skipped on a page detected as a soft 404, where raw and rendered are both the error shell.
How to fix it
Render the primary content on the server. In a framework that supports it, that is the default page mode rather than a client-only component:
export default async function Page() {
const article = await getArticle();
return <article>{article.body}</article>;
}The test is curl https://example.com/page | grep "some text from the page". If the text is not in the response, an agent reading raw HTML does not have it.
The common false positive is a page that is genuinely an application rather than a document, such as a dashboard behind a login. There is no content for an agent to read there and the finding does not apply. The result is info severity and does not move the score.
| Rule ID | ax/content-without-js |
| Category | Agent Experience |
| Scope | Per-page |
| Severity | info |
| Weight | 2/10 |
Enable / disable
Disable this rule
[rules]
disable = ["ax/content-without-js"]Disable all Agent Experience rules
[rules]
disable = ["ax/*"]Enable only this rule
[rules]
enable = ["ax/content-without-js"]enable replaces the default ["*"], so this is the only rule selected. Leave disable out: a rule that matches any disable pattern is skipped even when enable names it. Only an enabled setting under a rule’s own [rule_options] table overrides both lists.
Related rules
- ax/token-weight: how much of the HTML an agent pays for is text rather than markup.
- ax/markdown-response: serving a clean Markdown copy, which sidesteps the problem entirely.
- perf/browser-required: pages that need a browser to render at all.
- content/word-count: content length measured against a thin-content threshold.
Agent experience findings ship in every audit next to the SEO, performance and security rules. See Generative engine optimization for how an agent works through a report.
References
Check your site
Run squirrel audit https://example.com and open the Agent Experience section of the report. Each page shows its raw and rendered word counts. Cloud audits render the pages.