Foundational pillar / check h1-presence
H1 presence and uniqueness
Every indexable page should declare exactly one non-empty H1 element distinct from the document title.
By Shimon Carroll, Founder, SEO for AI Agents · Last updated
What this check measures
The check verifies that the rendered DOM (and where possible the raw HTML) contains exactly one H1 element, that the H1 is non-empty, and that the H1 text is distinct from the document <title> text. We measure on both the raw HTML returned by the lightweight crawler and, when render-parity is in question, on the Playwright-rendered DOM.
Why it matters
The H1 is the single largest on-page semantic signal for both classic Googlebot and citation-aware LLM crawlers. A missing H1 (most often replaced by an H2 or a styled <div>) forces the crawler to fall back on the <title>, weakening passage-extraction and topic disambiguation. Multiple H1 elements (common on themes that wrap the site logo in an H1 and the page title in a second H1) split the topical signal. The HTML Living Standard now permits multiple H1 elements per page as a structural matter, but search-engine behavior continues to reward a single H1 per indexable page, and AI engines consistently treat the first H1 as the canonical page topic.
How we score it
PASS if exactly one H1 is present and non-empty AND the H1 text differs from the document <title>. FAIL otherwise. Severity defaults to HIGH (foundational pillar). The vertical adapter does not override H1-presence severity for any of the launch verticals; the check fires identically on every audit.
Confidence-flag rules
Confidence is HIGH when the H1 is present in the raw HTML (no JS render required to verify). Confidence drops to MEDIUM when the H1 is only present in the JS-rendered DOM (the check passes but the page is at risk on AI crawlers that do not execute JS). Confidence is LOW only when the HTML response was partial or compressed-but-undecodable; the finding is suppressed in that case rather than reported with a low-confidence flag.
Common mistakes
- Wrapping the site logo image in an H1 element so every page reports two H1 elements (the logo H1 plus the page-title H1).
- Rendering the H1 via React after hydration so the raw HTML contains an empty container and AI crawlers (GPTBot, ClaudeBot, PerplexityBot) see no H1.
- Using a styled <div class="h1"> instead of a semantic H1 because the design system treats heading levels as visual classes rather than structural elements.
- Setting the H1 to the exact same string as the <title>, which forfeits the extra disambiguation signal both surfaces could provide.
How to fix it
Place a single H1 element near the top of the main content area, containing a concise, intent-matched description of the page. Keep the <title> distinct from the H1 (the title can include the brand suffix; the H1 can be cleaner). Verify in the raw HTML (not just the rendered DOM) by viewing source or running a curl that does not execute JavaScript. If the framework renders the H1 only on the client, move it into a Server Component or a static export so the H1 is in the initial HTML payload.
Primary sources
- HTML Living Standard, the h1 element
WHATWG
- Google Search Central, heading guidelines
Google Search Central
- AI crawler behavior, GPTBot and JS rendering
OpenAI
Changelog
- · Initial publication. Single-H1 rule with multi-H1 exception explicitly addressed.