Skip to Content
Semantic HTMLIssue 57

Page regions not marked up with semantic HTML5

What Is This Issue

This issue checks whether your web pages use HTML5 semantic landmark elements correctly. Semantic landmarks are special HTML tags that clearly define different sections of a page, making it easier for browsers, search engines, and assistive technologies to understand the page structure.

The audit verifies the presence and proper use of these core semantic elements:

  • <main> — Identifies the primary content of a page
  • <nav> — Marks navigation menus
  • <header> — Defines page or section headers
  • <footer> — Defines page or section footers
  • <article> — Identifies self-contained content
  • <section> — Groups related content
  • <aside> — Marks complementary content (sidebars, related links)

A passing implementation should have:

  • Exactly one <main> element per page (or an ARIA role=“main” as a fallback)
  • Appropriate landmark elements where semantically meaningful
  • Landmark elements that contain actual content (not empty)
  • No block-level elements nested inside inline elements

Example of good implementation:

<body> <header> <h1>Website Title</h1> <nav>Navigation menu</nav> </header> <main> <article> <h2>Article Title</h2> <p>Article content...</p> </article> </main> <aside> <p>Related links</p> </aside> <footer> <p>Copyright information</p> </footer> </body>

Why Is This Important

Using semantic HTML5 landmarks is crucial for several reasons:

  • Accessibility: Screen readers and assistive technologies rely on landmarks to help users navigate page content efficiently. Missing or incorrect landmarks make your site inaccessible to visually impaired users.

  • SEO and Rankings: Search engines use semantic structure to better understand page content and context. Clear landmarks help search engines identify primary content versus navigation, sidebars, or footers, which can improve how your pages are indexed and ranked.

  • User Experience: Semantic landmarks improve keyboard navigation and make your site more usable for people relying on assistive technologies.

  • AI Search / AEO (Answer Engine Optimization): As AI-powered search engines and voice assistants become more prevalent, they use semantic HTML to extract and understand content structure. Proper landmarks help AI systems identify the most relevant content to answer user queries.

Resolving this issue improves your overall SEO health score by ensuring your site is accessible, well-structured, and easily understood by both search engines and assistive technologies.

How XeoPix Detects This

XeoPix uses a straightforward process to identify semantic HTML issues:

  1. Fetches the page: XeoPix downloads the HTML content of the page (respecting robots.txt rules) with a reasonable timeout.

  2. Parses the HTML: The crawler analyzes the static HTML structure without executing JavaScript (though it can detect if client-side rendering may require additional checks).

  3. Checks for required landmarks: XeoPix looks for the presence of key semantic elements:

    • Checks if there’s exactly one <main> element (or role="main" attribute)
    • Checks for presence of <nav>, <header>, and <footer> elements
    • Identifies <article>, <section>, and <aside> elements
  4. Validates landmark usage: For each semantic element found, XeoPix checks:

    • Whether the element contains actual content (not just empty or whitespace)
    • Whether there are multiple <main> elements (which is incorrect)
    • Whether non-semantic <div> elements are being used as landmarks without ARIA roles
  5. Checks for nesting errors: XeoPix identifies incorrect HTML structure where block-level elements (like <div>, <p>, headings) are placed inside inline elements (like <a>, <span>, <strong>).

  6. Generates issues: Based on these checks, XeoPix flags problems with appropriate severity:

    • CRITICAL: Missing <main> landmark
    • WARNING: Multiple <main> elements, missing navigational landmarks, or empty semantic elements
    • SUGGESTION: Non-semantic wrappers that should use semantic elements

The detection focuses on the static HTML delivered by the server. For pages that heavily rely on client-side JavaScript to generate content, XeoPix may recommend additional rendering-capable validation.

How To Fix

  1. Add a <main> element: Ensure every page has exactly one <main> element that wraps the primary content. If you cannot use the <main> tag (e.g., legacy systems), add role="main" to the appropriate container div.

  2. Use semantic tags appropriately: Replace non-semantic <div> elements with appropriate semantic landmarks:

    • Use <nav> for navigation menus
    • Use <header> for page or section headers
    • Use <footer> for page or section footers
    • Use <article> for self-contained content pieces
    • Use <section> for grouping related content
    • Use <aside> for sidebars or complementary content
  3. Ensure landmarks contain content: Make sure semantic elements are not empty. They should contain meaningful content, headings, or links.

  4. Fix multiple <main> elements: If your page has multiple <main> elements, consolidate them into a single <main> element.

  5. Add ARIA roles as fallbacks: When semantic tags cannot be used, add appropriate ARIA roles (role="navigation", role="banner", role="contentinfo", etc.) to non-semantic elements.

  6. Fix nesting errors: Ensure block-level elements are not placed inside inline elements (e.g., don’t put a <div> inside an <a> tag).

  7. Handle client-side rendered content: If your site uses JavaScript to render content client-side, ensure the initial HTML shell includes proper semantic landmarks, or use server-side rendering to deliver semantic HTML to crawlers.

What We Store

Storage Level

Page Level


Database Table / Prisma Model

PageSemanticElement


Stored Fields

FieldTypeDescription
genericStructuralContainersString[]Array of generic structural container elements found (div, span, etc.)

Detection Dependencies

  • HTML Document
  • DOM Structure Analysis

Examples

Example 1: Proper semantic HTML structure

Scenario: A typical webpage with clear content sections.

Problematic state (what fails):

<body> <div id="header"> <h1>Website Title</h1> <div id="nav">Navigation menu</div> </div> <div id="content"> <div class="post"> <h2>Article Title</h2> <p>Article content...</p> </div> </div> <div id="sidebar"> <p>Related links</p> </div> <div id="footer"> <p>Copyright information</p> </div> </body>

Corrected state (what passes):

<body> <header> <h1>Website Title</h1> <nav>Navigation menu</nav> </header> <main> <article> <h2>Article Title</h2> <p>Article content...</p> </article> </main> <aside> <p>Related links</p> </aside> <footer> <p>Copyright information</p> </footer> </body>

Example 2: Multiple main elements (incorrect)

Scenario: Page incorrectly has multiple main elements.

Problematic state (what fails):

<body> <main>First main content</main> <main>Second main content</main> </body>

Corrected state (what passes):

<body> <main> <section>First content section</section> <section>Second content section</section> </main> </body>

Example 3: Empty semantic elements

Scenario: Semantic elements without content.

Problematic state (what fails):

<body> <header></header> <main></main> <footer></footer> </body>

Corrected state (what passes):

<body> <header> <h1>Site Title</h1> </header> <main> <p>Page content here</p> </main> <footer> <p>&copy; 2024 Company Name</p> </footer> </body>

Unit Test

Test File

__tests__/seo-audit-checks/semanticHtml/issue-142-key-regions-use.test.js

Purpose

This unit test validates that the SEO audit correctly detects whether a page uses semantic HTML5 landmark elements (<main>, <nav>, <header>, <footer>, <article>, <aside>, <section>) for key regions, and flags pages that rely on generic <div>/<span> containers instead.

Tested Function

runSemanticHtml from toggleGroups/semanticHtml.js

Issue Information

  • Issue Number: 141
  • Issue Code: key_regions_use
  • Toggle Group: semanticHtml

Test Scenarios

Positive Test Cases

  1. Page has all key semantic HTML5 elements — When the page contains <header>, <nav>, <main>, and <footer>, no issue should be reported.
  2. Page has main, nav, header, and footer — When the page contains these four core semantic elements even if missing others like <article>, <aside>, or <section>, no issue should be reported.
  3. Multiple semantic elements present — When the page contains <header>, <nav>, <main>, <article>, <aside>, <section>, <figure>, <figcaption>, and <footer>, no issue should be reported.

Negative Test Cases

  1. Missing <main> element — When the page is missing the <main> element, the issue should be reported with missingElements.main set to true.
  2. Missing <nav> element — When the page is missing the <nav> element, the issue should be reported with missingElements.nav set to true.
  3. Missing <header> element — When the page is missing the <header> element, the issue should be reported with missingElements.header set to true.
  4. Missing <footer> element — When the page is missing the <footer> element, the issue should be reported with missingElements.footer set to true.
  5. Relies on generic <div>/<span> containers — When the page uses only generic containers (e.g., <div class="container">, <div class="wrapper">, <div class="content">, <div class="sidebar">), the issue should be reported with reliesOnGenericContainers set to true.
  6. No semantic HTML5 elements at all — When the page has no semantic elements (only <div> and <span>), the issue should be reported with all missingElements flags set to true and semanticElements as an empty array.

Boundary Cases

  1. Payload contains detected semantic elements list — The function’s return payload should include the semanticElements array listing all detected semantic HTML5 tags.
  2. Payload contains detected generic structural containers — The function’s return payload should include the genericStructuralContainers array listing all detected generic class names.

Edge Cases

  1. Empty body — When the page has an empty <body>, the issue should be reported (missing all key regions).
  2. Minimal content — When the page has minimal content (basically empty body), the issue should be reported.
  3. Generic class patterns detection — When the page uses generic class names like container, wrapper, row, col, grid, layout, section, content, main, page, block, box, inner, outer, flex, sidebar, the issue should be reported with reliesOnGenericContainers set to true and all detected class names listed.
  4. Mixed semantic and generic elements — When the page has some semantic elements (<header>, <nav>, <footer>) but also uses generic containers, the issue should be reported with reliesOnGenericContainers set to true.
  5. Semantic elements with generic classes — When semantic elements themselves have generic class names (e.g., <header class="wrapper">), the issue should still be reported and the generic class names should be detected.
  6. Malformed HTML — Malformed HTML (unclosed tags) should not cause the function to throw an error.

Expected Outcome

Pass

The issue should be reported when:

  • The page is missing any of the core semantic elements (<main>, <nav>, <header>, <footer>)
  • The page relies on generic <div>/<span> containers with structural class names (container, wrapper, row, col, etc.)
  • The page has an empty or minimal body (missing all key regions)

Fail

The issue should not be reported when:

  • The page contains all core semantic elements (<main>, <nav>, <header>, <footer>)
  • The page contains all four core elements, even if <article>, <aside>, and <section> are missing

Validation

  • Correct issue detection — Verifies that missing required semantic elements triggers the issue with the correct payload.
  • No issue detection when expected — Verifies that pages with proper semantic structure do not trigger the issue.
  • Payload validation — Verifies the semanticElements and genericStructuralContainers arrays in the return payload.
  • Metadata validation — Verifies that missingElements correctly identifies which elements are missing, and reliesOnGenericContainers is set appropriately.
  • Error handling — Verifies that malformed HTML does not cause runtime errors.
  • toggleGroups/semanticHtml.js
  • issueCodes.js
  • utils/issues.js
  • utils/context.js

Coverage Summary

  • Covers all four core semantic elements (<main>, <nav>, <header>, <footer>) individually
  • Covers generic container detection with 16 common structural class name patterns
  • Covers mixed scenarios (partial semantic elements + generic containers)
  • Covers empty and minimal content edge cases
  • Covers malformed HTML resilience
  • Validates both the issues array and the function return payload

References

Last updated on