What are the rules for H1 headings?

h1-heading-issues page

The issue

A page with no <h1>, or with several, doesn’t say plainly what it is about. Screen reader users who jump to the main heading find nothing, or several candidates. Search engines lose the clearest statement of the page’s topic on the page itself.

The cause is usually the template or a component. A layout that omits the heading leaves every page without one. A hero or card component that carries its own <h1> adds a second one to every page it is placed on. An <h1> with no text counts as a problem too.

Scope

Each page is checked on its own HTML. Because the causes live in templates and components, one fix usually clears many pages at once.

How to check you have it

  • In probeo: the page reports Missing <h1>, Multiple <h1> elements (N found), or Found N empty <h1> element(s).
  • By hand: in the browser console, run document.querySelectorAll('h1') and count the results. Check that each one has text.
  • With a tool: the headings view in an accessibility checker such as WAVE lists every heading on the page in order.

The fix

Give each page exactly one <h1> that names its topic, and use <h2> to <h6> for everything below it.

For a missing heading, add it to the template’s main content area. For several, keep the one that names the page and demote the others to <h2> or lower; components below page level shouldn’t use <h1> at all. Remove or fill any empty <h1>.

Done when: every page has one <h1> with text, at the top of its content, and the check above comes back clean.

Do not

  • Do not rely on the HTML5 outline algorithm to justify multiple <h1> elements.
  • Do not put the <h1> in a layout shell that doesn’t change between pages or routes.
  • Do not use <h1> for a logo or branding outside the main content.
  • Do not hide the <h1> with CSS.
  • Do not put <h1> elements inside reusable components.

FAQ

Does the HTML5 outline algorithm make multiple H1 elements valid?

No. The outline algorithm, which let each <section> start again at <h1>, was never implemented by browsers or screen readers and was removed from the HTML standard in 2022. Headings are read at the level they are written.

How do single-page applications handle H1 across route changes?

The <h1> has to live inside the routed content, so it changes with each view. One placed in the layout shell stays the same on every route. Server-rendered and prerendered routes get this right by default; client-only apps should check the heading after each navigation.

Should the H1 match the title element exactly?

No. The title names the page in search results and browser tabs, and often carries the brand. The <h1> names it for someone already on the page. Probeo flags a title identical to the <h1> as a warning, because the two do different jobs.

Can dynamic heading changes cause issues after initial render?

They can. A heading added after a slow API call may be missing when a crawler takes its snapshot, and a heading that changes while a screen reader user is on the page is disorienting. Render the <h1> with the rest of the page.

It doesn’t invalidate structured data. It removes one of the plainest signals of what the page covers, which search engines read alongside the markup.

What happens when a CMS or component library injects extra H1 elements?

Every page using that component gets a second <h1>. Fix it in the component: headings inside components should be <h2> or lower, or take their level as a setting. Check the rendered HTML, not just the template, since composition is where the duplicates appear.

Which product detects this

Probeo checks this on every page of your site as part of Site Clarity. This page explains one instance; the product tells you every page that has it.