# Document does not have a main landmark: what it means and how to fix it

**Audit ID:** `landmark-one-main` · **Category:** Accessibility

This Lighthouse audit fails when the page has no `<main>` element. Screen reader users rely on landmarks to skip past navigation and jump directly to primary content. Missing it makes your page significantly harder to use with assistive technology.

## TL;DR

- **What:** The page has no `<main>` element (or multiple, which also fails).
- **Why it matters:** Screen readers use landmarks for keyboard-free navigation.
- **Fix:** Wrap your page's primary content in `<main>`, exactly once per page.

## What the audit checks

Lighthouse confirms the rendered DOM contains exactly one `<main>` element (or an element with `role="main"`). Pages missing it score 0 on this audit.

## Why it matters

Screen reader users (and keyboard users via the rotor or "skip links") navigate web pages by landmarks: `<header>`, `<nav>`, `<main>`, `<aside>`, `<footer>`. With a missing `<main>`:

- "Skip to main content" links have no target
- Screen reader landmark navigation skips the page entirely
- Document outline is broken for assistive tech

## The fix

Wrap your page's primary content, everything that isn't header, nav, sidebar, or footer, in a single `<main>`:

```html
<!-- BEFORE: no landmark -->
<body>
  <header>...</header>
  <nav>...</nav>
  <div class="content">
    <h1>Page title</h1>
    <p>Main content...</p>
  </div>
  <footer>...</footer>
</body>

<!-- AFTER: <main> wraps primary content -->
<body>
  <header>...</header>
  <nav>...</nav>
  <main>
    <h1>Page title</h1>
    <p>Main content...</p>
  </main>
  <footer>...</footer>
</body>
```

## Common framework-specific guidance

### React / Next.js

In your root layout:

```jsx
export default function Layout({ children }) {
  return (
    <>
      <Header />
      <main>{children}</main>
      <Footer />
    </>
  );
}
```

### WordPress

Most modern themes wrap the loop in `<main>` already. If yours doesn't, edit `header.php` or the appropriate template part and add `<main id="content">` before the loop.

### Vue / Nuxt

In `default.vue` layout:

```vue
<template>
  <Header />
  <main>
    <slot />
  </main>
  <Footer />
</template>
```

## Pitfalls to avoid

- **Don't nest `<main>` inside `<header>` or `<footer>`**, the semantics conflict.
- **Don't use multiple `<main>` elements per page.** If you have tabs or accordions, keep `<main>` as the outer wrapper.
- **Don't use `<main role="main">`**, the role is implicit; the explicit role is redundant.
- **`<main>` should not be inside `<article>` or `<section>`.** It's a top-level landmark.

## Verification

1. Re-run Lighthouse. The `landmark-one-main` audit should pass.
2. Test with a real screen reader: VoiceOver (Mac: Cmd+F5) or NVDA (Windows, free). Use landmark navigation (VO+U → Landmarks; NVDA: D for next landmark).
3. Use the [axe DevTools](https://www.deque.com/axe/devtools/) extension for a deeper accessibility check.

## Related audits

- [Heading order](/audits/heading-order), semantic structure
- [Image alt attributes](/audits/image-alt), screen reader content for images
- [Color contrast](/audits/color-contrast), visual accessibility

---

Audit your URL at https://lighthouse-md.com.
