Fix "has an H1 in its body" or "skips a heading level" (DS-A02)
The page title is the H1. Start body headings at
Symptom
Section titled “Symptom”reed check or reed build fails with one or more of these:
✗ [DS-A02] content file "guides/setup.mdx" has an H1 in its body (the H1 comes from frontmatter "title") ✗ [DS-A02] content file "guides/setup.mdx" skips a heading level (h2 → h4) ✗ [DS-A02] content file "guides/setup.mdx" skips a heading level (h1 → h3)check failed.The last form confuses people most: the page has no # heading anywhere, yet the
message says h1 → h3. That is a page whose first heading is ###.
Reed renders frontmatter title as the page’s H1. The body’s headings are checked as if
that H1 sits directly above them, so two rules apply:
- No
#in the body. A second H1 gives the page two competing top-level headings, and a screen reader announces both. - Each heading may go at most one level deeper than the one before it. Going back
up,
####to##, is always fine; going down more than one step is not.
Because the implied H1 counts, rule 2 applies to your first body heading too. A page
that starts at ### has skipped h2, which is the h1 → h3 message.
Some common ways to get here:
- A page imported from another platform keeps its old
# Titleline under the new frontmatter. - A short page begins at
###because##“looked too big”. - A section is deleted and its
####children are left under a##. - Headings inside components count. A
###inside anAccordion,TaborStepis part of the same outline as the headings around it.
A # line inside a fenced code block is code, not a heading, and is never reported.
Remove the body H1
Section titled “Remove the body H1”Delete the # line and move its text into title if the title is not already right:
---title: Set up your projectdescription: Install Reed and build your first site.---
# Set up your project
## Installbecomes:
---title: Set up your projectdescription: Install Reed and build your first site.---
## InstallStart at ##
Section titled “Start at ##”If the page begins with ###, promote every heading one level, keeping their relative
structure:
### Install#### From npm#### From source### Configurebecomes:
## Install### From npm### From source## ConfigurePromote them all, not just the first — promoting only ### Install would leave
## Install followed by #### From npm, which is a new h2 → h4 error.
Close a skipped level
Section titled “Close a skipped level”For h2 → h4 in the middle of a page, either promote the deeper heading or add the
missing level between them, if the content really has that extra layer:
## Configure
#### Environment variablesbecomes:
## Configure
### Environment variablesFind them quickly
Section titled “Find them quickly”The message names the file and the two levels, but not the line. List a page’s headings with their line numbers:
grep -nE '^#{1,6} ' content/guides/setup.mdxRead the level column top to bottom. The first line must be ##, and no line may be
more than one # longer than the line before it. This also lists # lines inside code
fences; ignore those, since the check does.
Verify
Section titled “Verify”reed check 2>&1 | grep -c 'DS-A02'Expect 0, and a final check passed. After fixing, glance at the page’s table of
contents in reed dev. It is built from the same headings, so an outline that looks
flat or oddly nested there usually means a heading is still at the wrong level.
Related
Section titled “Related”- Pages — frontmatter and headings
- MDX pitfalls — the H1-in-the-body section
- Accessibility
- Diagnostics