Saltar al contenido principal
All Guides

HTML Rendering

Weight: 9% of your AX score. Most AI crawlers — GPTBot, ClaudeBot, CCBot, PerplexityBot — do not execute JavaScript. If your homepage is a JS-only shell, those agents see an empty page no matter how good your llms.txt or structured data are. This check verifies that the static HTML actually contains content.

Could not fetch homepage HTML

ax-audit could not retrieve any HTML from the root URL. The server returned an empty body, a non-2xx status, or timed out.

  • Verify curl -I https://your-site.com returns 200 OK.
  • Confirm your CDN / firewall isn't blocking the ax-audit/<version> User-Agent.
  • Make sure the homepage doesn't require an authenticated session.

No visible text content (JS-only shell)

The static HTML response contains no readable text — typical of a client-rendered SPA where the entire UI is built by JavaScript at runtime.

Pick the rendering strategy that matches your stack:

  • Next.js / Remix / Nuxt: use SSR or SSG for top-level routes (getServerSideProps, getStaticProps, route loaders).
  • Astro: already SSR by default — verify you're not in output: 'static' with all components flagged client:only.
  • SvelteKit: ensure +page.server.js or +page.js renders text content.
  • CRA / Vite SPA: add a prerender step (e.g. react-snap, vite-plugin-prerender) or migrate to a framework with built-in SSR.
How to verify
Run curl -s https://your-site.com | wc -w. If the word count is < 50, agents that don't execute JS will see almost nothing.

Sparse server-rendered content

Your homepage has < 80 words or < 500 characters of visible text in the static HTML. Some content is rendered server-side, but not enough for an agent to summarize the page.

  • Inline at least the hero copy, primary headings, and a paragraph of context.
  • If you ship a marketing page above-the-fold and a JS dashboard below-the-fold, server-render the marketing portion.
  • Avoid hydration patterns that strip text from the SSR output and re-inject it client-side.

Low text-to-markup ratio

Less than 5% of your HTML response is visible text — the rest is markup, scripts, and inline styles. This is a classic SPA-shell symptom.

  • Move large inline JSON state blobs (__NEXT_DATA__, Apollo cache, Redux state) to a deferred fetch when possible.
  • Lazy-load fonts, analytics, and third-party scripts. Defer non-critical bundles.
  • Server-render more text content above-the-fold.

Empty SPA mount point detected

ax-audit found an empty mount node like <div id="root"></div>, <div id="__next"></div>, or <div id="app"></div> with no children. That means the entire page is rendered client-side.

<!-- BAD — agents see nothing -->
<div id="root"></div>
<script src="/bundle.js"></script>

<!-- GOOD — SSR fills the mount point -->
<div id="root">
  <main>
    <h1>Site Title</h1>
    <p>Server-rendered hero copy that agents and search crawlers can read.</p>
  </main>
</div>
<script src="/bundle.js"></script>

Enable SSR or SSG in your framework. The mount node should already contain the rendered content before hydration runs.


No semantic landmarks

None of <main>, <article>, <section>, <header>, <footer>, or <nav> appear in your HTML. AI agents use these tags to identify the primary content region and discard chrome.

<body>
  <header><nav>...</nav></header>
  <main>
    <article>
      <h1>Page topic</h1>
      <p>Primary content...</p>
    </article>
    <section><h2>Secondary section</h2></section>
  </main>
  <footer>...</footer>
</body>

Few semantic landmarks

Fewer than three semantic tags found. Replace generic <div> wrappers with the appropriate landmark — <main> for the primary content, <header>, <nav>, <footer> for site chrome, <article> for self-contained content units.


No <h1> heading

Every page should have a single <h1> describing its topic. AI agents and search engines treat the H1 as the strongest topical signal for the page.

<main>
  <h1>Customer support knowledge base</h1>
  ...
</main>

Multiple <h1> headings

More than one <h1> on the page dilutes the topic signal. Demote secondary H1s to <h2> so the document outline reflects a clear hierarchy.


Empty <h1>

Your <h1> tag exists but contains no text — possibly because it's populated by JavaScript or only contains an icon/image. Add meaningful textual content so agents can identify the topic.

<!-- BAD -->
<h1><img src="/logo.svg" alt=""></h1>

<!-- GOOD -->
<h1>
  <img src="/logo.svg" alt=""> Acme Corp
</h1>

Heavy JavaScript without <noscript>

Your page ships more than 15 executable <script> tags but provides no <noscript> fallback. Agents that don't run JS (and users with JS disabled) will see a blank page.

<noscript>
  <p>This site works best with JavaScript enabled.
     For a no-JS overview, see our <a href="/llms.txt">/llms.txt</a>
     or <a href="/about">about page</a>.</p>
</noscript>

Missing alt attributes

Less than 90% of your <img> tags include an alt attribute. Agents (and assistive tech) rely on alt text to understand images they can't process visually.

  • Use a descriptive alt for content images: alt="Team photo at the 2026 conference".
  • Use alt="" (empty) for decorative images so screen readers and agents skip them cleanly.
  • Never omit the attribute entirely.