The page-has-heading-one rule flags a page that has no level-one heading – no h1 and no heading with aria-level="1". Screen reader users then cannot jump to the start of the content by heading. The fix is to mark up the visible page title as an h1.
What the rule means
The h1 names what a page is about: the article headline, the product name, "Opening hours". It is usually the first thing a screen reader user looks for after landing on a page. The rule checks the whole document once and passes as soon as it finds one of:
- an
h1element without aroleoraria-levelthat changes it, - an
h1–h6element witharia-level="1", - an element with
role="heading"andaria-level="1".
The heading has to be exposed to assistive technology – one inside display: none or aria-hidden="true" does not count – but it may be visually hidden. The rule does not check whether it is sensible or unique; several h1s pass too. While a modal dialog is open, axe lets the page pass, because the content behind the dialog is out of reach anyway.
Note: this is a best practice, not a WCAG failure in itself. WCAG does not require an h1. It relates to 1.3.1 Info and Relationships, because a page title that only looks like a heading carries no structure, and to 2.4.6 Headings and Labels.
Who is affected
Mainly blind and partially sighted people using a screen reader. Many press 1 (in NVDA and JAWS) or use the VoiceOver rotor to jump to the level-one heading and start reading there. The WebAIM screen reader survey has found for years that navigating by headings is the most common way to find information on a long page [4]. Without an h1, that jump either fails or lands on some sub-heading further down.
Why the check fails
- The page title is styled text: a
<p class="page-title">or<div class="hero__title">that looks like a heading. - The logo is the only
h1on the home page, and was then removed from all other templates. - Themes that start at
h2, expecting the editor to add theh1in the content – and the editor did not. - Title inside an image or slider: the headline is part of a hero image or a carousel slide with no text heading.
- Single-page apps that render the heading only after data has loaded, or not at all on some views.
How to fix it
Find the visible title of the page and change its element to h1. Keep the class so the design stays as it is.
<!-- Before: the title looks like a heading but is a paragraph -->
<body>
<header><a href="/">City Library</a></header>
<main>
<p class="page-title">Opening hours</p>
<h2>Main library</h2>
<p>Monday to Friday, 9:00 to 19:00</p>
</main>
</body>
<!-- After: the same title as an h1, same class, same look -->
<body>
<header><a href="/">City Library</a></header>
<main>
<h1 class="page-title">Opening hours</h1>
<h2>Main library</h2>
<p>Monday to Friday, 9:00 to 19:00</p>
</main>
</body>
Two rules of thumb:
- One
h1per page is the usual pattern, describing the page's own content – not the site name on every page. - Put it at the start of the main content, inside
<main>, so the heading and the main landmark lead to the same place.
How to test it manually
- Open the heading list: the free HeadingsMap extension, the WAVE extension's structure view, or a screen reader (NVDA: Insert + F7; VoiceOver: VO + U).
- Check that there is a level-one heading and that it names the page, not the site or a section.
- Press 1 in NVDA or JAWS: focus should land at the start of the page's content.
- The rule only checks that an
h1exists. A hiddenh1, a generic one ("Welcome") or one that repeats the site name passes the rule and still does not help.
Related WCAG criterion
None directly – page-has-heading-one is a best practice. It relates to 1.3.1 Info and Relationships and 2.4.6 Headings and Labels. Headings are also one way to meet 2.4.1 Bypass Blocks.
How Reviseberg reports it
Reviseberg runs page-has-heading-one on every crawled page. The rule checks the document as a whole, so each affected page counts as one occurrence; when a template drops the h1, every page built from it appears. The issue list shows the rule as a best practice with its severity, the number of pages and the points a fix gets you back; it never counts towards a WCAG criterion or appears in a compliance report. The detail view lists every affected page. You can mark a finding as "ignore" or "false positive" with a reason; every decision is logged.