What does your page’s region list say?
A screen reader user does not tab through your header. They press one key, get a list of the regions on the page, and jump. Enter any page and we show you that list — in order, in the words it is actually announced with.
Free, instant, no signup and no card. Nothing is stored.
Free, instant, no signup and no card. We read the HTML your server sends for that one page. Nothing is stored.
The list nobody who built the page has ever seen
No browser shows it to you. It is not in the rendered page, it is not in view-source in any readable form, and it does not appear in a screenshot. It is assembled by the browser from your tags and your role attributes, handed to assistive technology, and opened by a keystroke you have probably never pressed. So it is the one part of a site that ships unreviewed by definition — not because anyone was careless, but because there was nowhere to look.
Here is what it reads on three sites that are visibly trying, read live on 22 September 2026:
nasa.gov banner · banner · search · Primary navigation, navigation ·
search · main · contentinfo
→ two unnamed banners, two unnamed searches
developer.mozilla.org
banner · navigation · navigation · contentinfo
→ two unnamed navigations, and no main region at all
gov.uk Cookies on GOV.UK, region · banner ·
(labelled by #super-navigation-menu-heading), navigation ·
Site-wide, search · main · search · contentinfo
→ named, distinct, and the one that reads cleanestNone of those is a conformance failure, and NASA’s two banners are a mobile header and a desktop header that are each correct on their own. That is the point: this is a class of defect that survives every review a serious team runs, because the artefact it lives in is one nobody is shown.
What WCAG actually says about landmarks
Less than most checkers imply. No success criterion requires a page to have a <main>, or a banner, or any landmark at all. SC 1.3.1 Info and Relationships asks that structure conveyed visually be available programmatically, and headings alone can satisfy it. SC 2.4.1 Bypass Blocks asks for a way past repeated blocks, and lists landmarks (technique ARIA11) as one sufficient way — with a skip link as another, which is why a page with a working skip link and no landmarks conforms.
So this checker calls exactly three things failures, and all three are markup contradicting itself: two elements both claiming to be the main region, a label pointing at an element that does not exist, and a landmark hidden from the technology it exists to serve. Everything else is reported for a look, with the criterion named where one genuinely applies and left off where it does not.
That restraint is the tool. Telling a stranger their working site “fails WCAG” because it has no <aside> is how accessibility scanners lose the room.
What this checker refuses to call a failure
Landmarks are unusual: the defect and the correct shape are often the same tag, and what separates them is how deeply it is nested. So the negatives are pinned as hard as the positives, by scripts/check-landmark-audit.mjs in the build:
<!-- correct — scoped to the article, NOT a second banner --> <main><article><header>Post title</header></article></main> <!-- correct — generic container, exactly like a div --> <section>…</section> <!-- correct — redundant, harmless, never reported --> <nav role="navigation" aria-label="Primary">…</nav> <!-- correct — this IS the fix for duplicate navs --> <nav aria-label="Primary">…</nav> <nav aria-label="Footer">…</nav>
<!-- fails 1.3.1 — two main regions, ambiguous jump target --> <main>…</main> <div role="main">…</div> <!-- fails 1.3.1 — ARIA drops the name silently, no fallback --> <nav aria-labelledby="nav-heading">…</nav> <!-- #nav-heading doesn't exist --> <!-- the common one — the list reads "navigation, navigation" --> <header><nav>…</nav></header> <footer><nav>…</nav></footer>
A <header>, <footer> or <aside> inside <article>, <aside>, <main>, <nav> or <section> exposes no role at all, per the HTML accessibility mapping — so it is never counted, never reported, and never called a duplicate. Every blog post on the internet has a nested <header>, which is what makes that the loudest false positive available here.
And the honest gap: we read the HTML your server sends and do not run your JavaScript. A page whose markup has no landmarks and almost no content is reported as verify — a client-rendered shell — rather than as a page with an empty region list.
Two things both claim to be the main region
FailsWCAG 2.1 SC 1.3.1 Info and Relationships (Level A)
More than one element on this page is a main landmark — usually a <main> element plus a div carrying role="main", left behind when the markup was modernised and the ARIA was not removed. A page has one main region by definition, so the structure being exposed is not the structure that exists. The jump-to-main command now has two destinations and takes the first, which is often the wrong one.
A region's label points at something that isn't there
FailsWCAG 2.1 SC 1.3.1 Info and Relationships (Level A)
A landmark carries aria-labelledby with an id that does not exist anywhere in this page's HTML. ARIA does not fall back when a reference is broken — it does not use the element's own text, and it does not warn. The name is simply dropped and the region announces as the bare role word, while the markup looks labelled in every code review it will ever get.
A region is hidden from the technology it exists for
FailsWCAG 2.1 SC 1.3.1 Info and Relationships (Level A)
A landmark carries aria-hidden="true", so it and everything inside it are removed from the accessibility tree while staying visible on screen. This is nearly always a decoration attribute that drifted onto a container. On a main landmark it deletes the page: a screen reader user gets a document with a header, a footer and nothing between them.
Two regions announce as exactly the same thing
ReviewWCAG 2.1 SC 1.3.1 Info and Relationships (Level A)
Two or more landmarks share a role and have no name to tell them apart, so the region list reads "navigation, navigation" — or three times over on a page with a header menu, a sidebar and a footer sitemap. The list is a shortcut, and a shortcut with identical entries makes the reader open each one to find out which is which. This is the most common landmark defect on the web and it takes one attribute to fix.
There is no main region
ReviewWCAG 2.1 SC 2.4.1 Bypass Blocks (Level A)
Nothing on this page is a main landmark, so the single most used screen reader shortcut — jump past the header, straight to the content — does nothing here, on every page of the site. This is NOT automatically a failure: ARIA11 is one sufficient technique for 2.4.1 and a working skip link is another, so a page with a real skip link already meets the criterion. It is on this list because <main> is one tag, it replaces a div you already have, and it is the difference between arriving at the content and tabbing to it.
Your <header> is not the page banner
ReviewWCAG 2.1 SC 1.3.1 Info and Relationships (Level A)
Every <header> or <footer> on this page is nested inside an <article>, <aside>, <main>, <nav> or <section>. Per the HTML accessibility mapping those are scoped to their section and expose no role at all — they are not banner or contentinfo landmarks, and the browser is right about that. The markup reads as though the page has a banner. The region list does not contain one.
A region is named after its own role
ReviewWCAG 2.1 SC 1.3.1 Info and Relationships (Level A)
A landmark's accessible name is the role word itself — aria-label="Navigation" on a <nav>, aria-label="Main" on a <main>. The role is appended when it is announced, so the reader hears "navigation navigation". It is not a conformance failure and nothing breaks; it is a label that spent itself saying what the browser was going to say anyway, on the one element where a distinguishing word was free.
The page is missing a banner or a footer region
ReviewThis page has landmarks, but not the full set a reader arrives expecting: a banner (the site header), a main region, and contentinfo (the site footer). No success criterion requires all three — this is a convention, not a rule, and a page without one is not failing anything. It is worth a line because the region list is most useful when it is predictable, and because the missing one is almost always a <div class="header"> that nobody renamed.
Some <section> elements are not regions
ReviewA <section> only becomes a region landmark when it has an accessible name — an aria-label, or an aria-labelledby that resolves. Without one it is exposed as a generic container, exactly like a div. That is correct, ordinary markup and it is not a defect: this is here because teams frequently believe otherwise, and ship a page of nameless <section> elements expecting a navigable outline that no screen reader will ever show.
This page has no regions at all
ReviewWCAG 2.1 SC 2.4.1 Bypass Blocks (Level A)
No landmark of any kind was found in the HTML: no <main>, no <nav>, no <header> or <footer> at the top level, and no role attribute putting one there. The region list this page offers a screen reader user is empty, so landmark navigation — the primary way they move around a page they have not seen before — is unavailable, and the only way past your header is the skip link, if there is one.
We cannot see this page's regions
VerifyThe HTML your server sent contains no landmarks and almost no content — it looks like a client-rendered shell that mounts its real markup after JavaScript runs. Whatever regions this page has are created in the browser, so this check has nothing to read and an empty result here is not a result. It is also what a crawler that does not execute your JavaScript sees.
The fix, in full
Four tag names and two attributes, all of them in the layout template, which is why fixing it once fixes every page.
<body>
<header> <!-- banner -->
<nav aria-label="Primary">…</nav> <!-- navigation, "Primary" -->
</header>
<main>…</main> <!-- main — exactly one -->
<aside aria-label="Related">…</aside> <!-- complementary -->
<footer> <!-- contentinfo -->
<nav aria-label="Footer">…</nav> <!-- navigation, "Footer" -->
</footer>
</body>That is a region list of six entries, every one of them distinguishable, and it costs two aria-label attributes over the markup most sites already have. The two words in those labels are the entire difference between a shortcut and a list the reader has to open one by one.
Then resist adding more. Past about eight regions the list takes as long to read as the page, which is the failure mode of every well-intentioned landmark cleanup: a dozen named <section> elements that turn a shortcut back into a scan.
And check the other half of SC 2.4.1 while you are in there. If your page has no main region, the skip link is the only bypass mechanism you have left — the skip link checker follows its href and tells you whether it still points at anything.
Common questions
- What is a landmark, in one sentence?
- A region of the page the browser hands to assistive technology as a named destination — banner, navigation, main, complementary, contentinfo, region, form and search. A screen reader user presses one key and gets the list of them, then jumps. It is the equivalent of glancing at a page and going straight to the bit you want, and it is the primary way somebody moves around a site they have not seen before.
- Does WCAG require landmarks?
- No, and any tool that tells you otherwise is overselling. SC 1.3.1 Info and Relationships asks that structure conveyed visually be available programmatically, which headings alone can satisfy. SC 2.4.1 Bypass Blocks asks for a way past repeated blocks, and lists landmarks (technique ARIA11) as one sufficient way and a skip link as another — so a page with a working skip link and no landmarks at all conforms. That is exactly why this checker calls only three things failures, and all three are markup contradicting itself.
- So what does it actually call a failure?
- Three things. Two elements both claiming to be the main region, which makes the jump-to-main command ambiguous. An aria-labelledby pointing at an id that does not exist, where ARIA silently drops the name rather than falling back — so the markup looks labelled forever. And aria-hidden="true" on a landmark, which deletes the region and everything inside it from the accessibility tree while leaving it on screen. Each one is a structure that was declared on purpose and then declared wrongly, which is what 1.3.1 is for.
- Why does "navigation, navigation" matter?
- Because the region list is a shortcut, and a shortcut with identical entries is not one. A page with a header menu, a sidebar and a footer sitemap gives a reader three entries that all say "navigation", so they have to open each one to find out which is which — which is more work than tabbing, the thing the list existed to avoid. Two aria-labels fix it: aria-label="Primary" and aria-label="Footer". This is the most common landmark defect on the web.
- My <header> is inside <article>. Isn't that a banner?
- No, and this is the trap that makes naive landmark checkers useless. Per the HTML accessibility mapping, a <header> or <footer> inside <article>, <aside>, <main>, <nav> or <section> is scoped to that section and exposes no role at all — it is not a banner and not contentinfo. The same rule applies to <aside>, which is only complementary at the top level. Every blog post on the internet has a nested <header>, so a checker that counted them would report duplicate banners everywhere. This one tracks nesting and does not.
- Are my <section> elements regions?
- Only the ones with an accessible name. A <section> with no aria-label and no resolving aria-labelledby is exposed as a generic container, exactly like a div — that is the spec, not an oversight, and it is not a defect. It is worth saying because teams routinely ship a page of nameless sections expecting a navigable outline that no screen reader will ever show them. The same rule applies to <form>: nameless, and it is not a form landmark.
- Is <nav role="navigation"> wrong?
- It is redundant and completely harmless — the browser maps the same role either way — and this checker never reports it. The first rule of ARIA is not to use it where HTML already does the job, so it is worth removing on a tidy-up, but it breaks nothing and it is not what you came here for.
- How many landmarks should a page have?
- Few enough that the list is still a shortcut. Banner, main, contentinfo and one or two navigations covers most pages. Once you are past about eight, scanning the region list costs as much as scanning the page, and the reader stops using it. If you are adding names to a dozen <section> elements to make them regions, that is the direction to stop going in.
- Why did you say my page has no landmarks when it clearly does?
- Almost always because they arrive with your JavaScript. This reads the HTML your server sends, deliberately — it is fast, free and the same markup a crawler sees. When that HTML has no landmarks AND almost no content, the result is reported as verify rather than as a finding, and says so. The free WCAG 2.1 AA scan renders each page in a real browser and sees what mounts.
- Can you tell me if my landmark names are good?
- Only the narrow case where a name is the role word itself — aria-label="Navigation" on a <nav>, announced as "navigation navigation". Beyond that, no: "Section 2" is a name as far as any machine is concerned. Naming a region by what it contains rather than what it is remains a human decision, and it takes about four seconds per landmark.
- Does this store my domain?
- No. The check is an HTTP GET of the page you name, run inside the request and discarded when it answers. There is no account, no email field and no row written anywhere. If you go on to run the free scan, that one does keep a report so you can come back to it, which is the whole point of a report.
Keep reading
- Does your skip link actually work? →
- Is your heading outline navigable? →
- Is your ARIA being thrown away? →
- Can a keyboard reach everything a mouse can? →
- Did your CSS delete the focus ring? →
- What starts before anyone clicks? →
- What is your hamburger button called? →
- How many links say “click here”? →
- Is your page declaring a language? →
- The WCAG compliance tool →