Semantic HTML for search and AI: which element each part of the page should use

Semantic HTML gives every region of a page a name, and a crawler reads that tree before it reads your text. This chapter gives the element-per-region table, a one-line landmark audit, and the claim we refuse to make: Google says search can rarely depend on semantic meanings, so markup is a correctness fix, not a ranking lever.

Crawling & Indexing6 min read2804 views
Semantic HTML for search and AI: which element each part of the page should use

Semantic HTML means using the element that names what a block is — <nav> for navigation, <main> for the primary content, <article> for a self-contained item — instead of wrapping every block in <div>. Search engines and AI crawlers parse a page into a tree before they read a sentence, and these element names are the labels on that tree. This chapter is the element table, a one-line audit you can run on any URL, and the one claim we will not make.

Read this first

One page you can edit, and a way to view its source. That is the whole prerequisite; no build step and no tooling. If your question is what should each section say, that is a different chapter — how to structure content for AI covers the wording and the order. This chapter is about the wrapper around that text: which element should hold each block.

Two chapters sit beside this one. The headings inside these sections are covered in h1 tag SEO. And if you want to know how often real sites even do this, the measured answer is in the html main element across 27 homepages.

What semantic HTML changes, and what it does not

It does not add a ranking factor, and Google says so in its own starter guide: "The web in general is not valid HTML, so Google Search can rarely depend on semantic meanings hidden in the HTML specification" (Google Search Central, read 2026-09-26). We will not sell you a ranking lift from markup.

A landmark is a semantic element that names one region of a page. The five that matter most are <header>, <nav>, <main>, <aside> and <footer>. Each one gives a node in the document tree a role, so a consumer can say "the navigation is here" instead of inferring it from position and class names.

What that buys you is a fallback, not a guarantee. An assistive tool reads the landmarks directly. A crawler that ignores them loses nothing when they are present and still has the text when they are absent. The cost runs one way only, which is why the rest of this chapter is a table rather than an argument.

There is a second reason, and it is the one that applies to a site like ours. The document tree is also what an extractor walks to decide where a passage begins and ends. If your page is one <div> inside another <div>, every downstream tool has to guess. Giving the regions names does not make the guess right; it removes the need to guess.

Do it in this order

Four steps. Each one has a completion mark you can check before moving on.

  1. Sort the page into regions. List every top-level block a reader sees: the banner, the menu, the article, the sidebar, the footer. Done when each block on your list maps to one region, not to "the stuff at the top".
  2. Give each region its element. Use the table below. Done when no block is left inside a bare <div> purely because you were not sure what it was.
  3. Check the heading tree inside those regions. One <h1> that names the page, then the sections beneath it. Done when the headings alone read as an outline of the page.
  4. Run the audit below on the live URL. Done when the counts match the list you drew in step one. If a region you named does not appear, it is still a <div>.

Step four is the one people skip, because the first three are judgments and the fourth is a number. The number is the only part a reviewer can check without opening your editor.

The deliverable: an element table and a one-line audit

The table is the chapter compressed to one screen. Every row answers the same question: what is this block, and which element says so.

ElementNamesUse it forCommon mistake
<main>Primary contentThe one block the page exists to deliverA second visible one, or none at all
<header>A bannerSite banner; a section's title blockConfusing it with the document <head>
<nav>NavigationMain menu, breadcrumb trailWrapping every set of links in one
<article>A self-contained itemA post, a product, a commentUsing it for any group of paragraphs
<section>A titled groupA distinct part of the page with a headingUsing it where a <div> is the honest answer
<aside>Tangential contentRelated links, a pull-quoteUsing it to mean "on the left"
<footer>A footerSite footer; a section's closing metaPutting real navigation there instead of in <nav>
<figure>, <figcaption>A figure and its captionAn image or a code sample with a captionA caption that is really body text
<h1>–<h6>A heading and its levelThe outline of the pageChoosing a level for its font size
<time>A machine-readable datePublished and updated datesLeaving the date as a plain string

The second deliverable is one line you can run against any URL. It reads the HTML the server sent, not the page after JavaScript runs, so it sees what a crawler sees on the first pass.

curl -sL https://example.com \
  | grep -oE '<(main|nav|header|footer|article|section|aside|figure)[ >]' \
  | sort | uniq -c | sort -rn

Run it against Google's own SEO Starter Guide, the page that tells you to write good HTML, and this is what comes back on 26 September 2026:

ElementCount on the guide
<main>1
<nav>6
<header>0
<footer>0
<article>1
<section>2
<aside>2
<figure>0
<div>154

Read that table carefully, because it is not an argument that Google is wrong. It is one page, fetched once, and it is a documentation page rather than a product page. The point is narrower: the labels are uneven, and a machine reading your page does not know which of 154 boxes is the one that matters unless something says so.

Two things the count cannot see: a landmark that is present but hidden, and one that wraps almost the entire page. Both need eyes on the page, which is why the command is a floor and not a verdict.

What goes wrong

Three failures show up more than any others, and all three are invisible in a browser.

  1. One wrapper to rule them all. The page is a single <div> with everything nested inside. It renders perfectly and tells a parser nothing about where the content starts and stops.
  2. Landmarks that overlap. Two <main> elements, or a <nav> inside another <nav> for no reason. A landmark is a claim about a region, and two claims for one region cancel out. Our own measurement found one homepage shipping two visible <main> elements.
  3. Headings chosen by size. The level follows the CSS class, so the outline reads as a flat list with no relationship between sections. The fix is not to add headings; it is to decide what the page is about, then let the sizes follow.

Common questions

Does semantic HTML improve SEO?

Not by itself, and we will not claim it does. Google's starter guide says search "can rarely depend on semantic meanings". What it changes is how legibly your page describes itself to the tools that do read structure. Treat it as a correctness fix, not a lever.

What are HTML landmarks?

A landmark is a semantic element that names one region of the page. The common set is <header>, <nav>, <main>, <aside> and <footer>. Screen readers use them to move between regions, and parsers use them to locate the main content without counting pixels.

Should I use section or div?

Use <section> when the block has a heading and is a distinct part of the page. Use <div> when you need a container for styling and there is no meaning to express. A <div> used as a wrapper is honest; a <section> used as a wrapper is noise.

Can a page have more than one main element?

The specification allows more than one only when all but one are hidden. We could not find a case where two visible ones helped, and we did find one homepage that shipped two. Keep it to one.

The boundary worth saying plainly: this fixes the tree and nothing else. It will not rescue thin content, a page whose body only arrives after JavaScript runs, or a block that genuinely has no role. When the page describes itself correctly, the next job is getting it crawled and published, which is the part QueryWin works on.

Part of the QueryWin handbook · Level 2