Rule: h1-present
The H1 is your page's primary heading — the strongest on-page signal for its main topic. Search engines use it alongside the title tag to understand what the page is about. Zero H1s means no topic signal. Multiple H1s dilute the signal. This rule enforces exactly one H1 per page and is critical: missing H1s block CI builds.
What it checks
Indxel counts all <h1> elements in the rendered HTML. In crawl mode, it fetches the page and parses the DOM. In static scan mode, it analyses the page's server-rendered output. The count determines the result: exactly 1 = pass, 0 = error, 2+ = warning.
Thresholds
Exactly 1 H1 element found on the page
0 H1 elements found — no primary heading
2 or more H1 elements found — diluted topic signal
Edge cases
Hidden H1s (display: none, visibility: hidden, or hidden attribute) still count in the DOM. Indxel reads the HTML structure, not the visual rendering. A hidden H1 is still an H1.
H1 inside a <template> tag does not count — template content is not rendered in the DOM.
In component-based frameworks, a Layout might render an H1 for the site name, and the Page renders another H1 for the page title. This results in 2 H1s — a common source of the 'multiple H1s' warning.
An empty <h1></h1> counts as 1 H1 present (passes the count check). But an empty H1 provides no topic signal — it's technically valid but semantically useless.
H1s inside <article> elements are still counted. HTML5 outlining algorithm (which allowed per-section H1s) was never implemented by browsers or search engines.
Configuration
// indxel.config.ts
import { defineSEO } from "indxel";
export default defineSEO({
rules: {
"h1-present": true, // enabled by default (critical)
},
});
// Best practice: Only the page component renders the H1.
// Layout uses a logo/link for the site name:
// app/layout.tsx
<Link href="/" className="text-xl font-bold">Acme</Link>
// app/about/page.tsx
<h1>About Acme</h1> // the only H1 on the pageFrequently asked questions
Is multiple H1s really a problem?
Google's John Mueller has said Google can handle multiple H1s. But 'can handle' is not 'performs best with.' A single, clear H1 gives the strongest topic signal. Indxel flags multiple H1s as a warning (not error) because it's sub-optimal, not catastrophic.
Should the H1 match the title tag?
Not necessarily word-for-word, but they should be about the same topic. The title tag is for search results; the H1 is for on-page context. They can use different phrasing to target slightly different keyword variations.
What about SPA frameworks that render H1 client-side?
Indxel's static scanner checks server-rendered HTML. If your H1 is only rendered client-side after JavaScript execution, it won't be detected. Use SSR or server components to ensure the H1 is in the initial HTML.