Korte versie

Semantische opmaak betekent dat je HTML-elementen kiest op hun betekenis. Gebruik één <h1> voor de titel, <h2> en <h3> voor secties, <article> rond de blogpost, <figure> met <figcaption> voor beelden en <time> voor datums. Voeg JSON-LD als BlogPosting toe, zodat zoekmachines een expliciete beschrijving van je pagina krijgen.

Wat semantische opmaak voor SEO doet

Met semantische opmaak kies je elk HTML-element op wat het betekent, niet op hoe het eruitziet. Een <h1> is de titel, een <nav> is navigatie en een <time> is een datum. Zo begrijpen browsers, zoekmachines en hulpsoftware zoals schermlezers hoe je pagina in elkaar zit. Semantische HTML is geen truc om hoger te ranken. Het maakt je pagina wel makkelijker te lezen en te indexeren, en dat is de basis van goede SEO.

Elke blogpost begint met precies één <h1>: de titel van je artikel. Daaronder volg je een logische volgorde zonder niveaus over te slaan, met <h2> voor hoofdsecties en <h3> voor subsecties. Je artikel wordt daardoor scanbaar voor lezers en begrijpelijk voor machines.

Je kunt ook een id-attribuut aan je <h2>- en <h3>-elementen geven, meestal een korte versie van de kop met koppeltekens in plaats van spaties. Een inhoudsopgave linkt dan rechtstreeks naar die sectie met een link als #naam-van-het-id.

Alle voorbeelden in deze gids horen bij één verzonnen blogpost: “Je eerste moestuin aanleggen” van auteur Sam Voorbeeld op example.com. Zo zie je hoe de stukken samen één pagina vormen.

De basisstructuur van een blogpost

Hier is de basisstructuur van zo’n blogpost met semantische opmaak:

html
<!DOCTYPE html>
<html lang="nl">
  <head>
    <title>Je eerste moestuin aanleggen</title>
  </head>
  <body>
    <header>
      <a href="/">
        <img src="/logo.svg" alt="Moestuinblog, naar de homepage" />
      </a>
      <nav aria-label="Hoofdnavigatie">
        <!-- aria-label i.p.v. heading: navigatie hoort niet in de content-outline -->
        <ul>
          <li><a href="/">Home</a></li>
          <li><a href="/blog">Blog</a></li>
          <li><a href="/contact">Contact</a></li>
        </ul>
      </nav>
    </header>
    <main>
      <article>
        <h1>Je eerste moestuin aanleggen</h1>
        <h2>De juiste plek kiezen</h2>
        <p>Paragraaf over zon en schaduw.</p>
        <h2>De grond voorbereiden</h2>
        <p>Paragraaf over spitten en compost.</p>
        <h3>Compost zelf maken</h3>
        <p>Paragraaf over een compostbak.</p>
        <h2>Wat je in het eerste jaar zaait</h2>
        <p>Paragraaf over makkelijke groenten.</p>
      </article>
    </main>
    <footer>
      <nav aria-label="Footernavigatie">
        <ul>
          <li><a href="/privacy">Privacy</a></li>
          <li><a href="/contact">Contact</a></li>
        </ul>
      </nav>
      <p>&copy; 2026 Moestuinblog</p>
    </footer>
  </body>
</html>

Merk op dat de navigatie geen <h2> gebruikt. Koppen zijn er voor je content. Een navigatie benoem je met een aria-label op het <nav>-element. Zo blijft de koppenstructuur van je artikel schoon, en weet iemand met een schermlezer toch welke navigatie hij tegenkomt.

Landmarks: main, article, section en aside

Landmarks vertellen browsers en schermlezers waarvoor elk deel van een pagina dient. Een blogpost heeft er meestal vier nodig.

Gebruik <main> één keer per pagina, rond de inhoud die alleen op die pagina staat. Header, navigatie en footer blijven erbuiten.

Gebruik <article> voor een blogpost die op zichzelf staat: iets wat ook begrijpelijk blijft als je het ergens anders publiceert. De titel, de datum en de tekst horen er allemaal in.

Gebruik <section> voor een thematisch deel van een pagina met een eigen kop. Kun je er geen kop voor bedenken, dan is een <div> meestal de betere keuze.

Gebruik <aside> voor inhoud die bij de blogpost hoort maar er niet onmisbaar voor is, zoals een auteursblok of een lijst met verwante artikelen.

Hier is dezelfde blogpost twee keer: eerst opgebouwd uit gewone <div>-elementen, daarna met semantische landmarks.

html
<!-- Voor: elk blok is een div -->
<div class="content">
  <div class="post">
    <div class="title">Je eerste moestuin aanleggen</div>
    <div class="date">14 april 2026</div>
    <div class="text">Paragraaf over zon en schaduw.</div>
  </div>
  <div class="sidebar">Verwante artikelen</div>
</div>

<!-- Na: landmarks en koppen dragen de betekenis -->
<main>
  <article>
    <h1>Je eerste moestuin aanleggen</h1>
    <time datetime="2026-04-14">14 april 2026</time>
    <p>Paragraaf over zon en schaduw.</p>
  </article>
  <aside aria-label="Verwante artikelen">Verwante artikelen</aside>
</main>

Beide versies kunnen er op het scherm hetzelfde uitzien. Alleen de tweede vertelt een browser, schermlezer of crawler waar de blogpost begint en eindigt. Op deze site staat het artikel zelf in een <article>, en het auteursblok en de verwante artikelen eronder zijn <aside>-elementen. Dat kun je zelf nakijken in de paginabron.

Afbeeldingen en hun alt-teksten

Afbeeldingen verdienen dezelfde zorg als je tekst. Geef ze een beschrijvende bestandsnaam en een alt-tekst die zegt wat er te zien is of waarom het beeld er staat. Een alt-tekst is er in de eerste plaats voor toegankelijkheid. Daarnaast geeft hij zoekmachines context. Is een beeld puur decoratief, gebruik dan een leeg alt="", zodat een schermlezer het overslaat.

Zo ziet een beeld met bijschrift eruit in HTML:

html
<figure>
  <img
    src="/blog/moestuin-verhoogde-bakken.jpg"
    alt="Drie houten verhoogde bakken met sla, wortelen en bonen in een kleine stadstuin"
    width="1200"
    height="800"
  />
  <figcaption>Verhoogde bakken zijn handig als je grond zwaar of vervuild is.</figcaption>
</figure>

Een <figcaption> is een zichtbaar bijschrift dat het beeld aan je artikel koppelt. De alt-tekst beschrijft het beeld voor wie het niet ziet, het bijschrift is voor iedereen zichtbaar. Ze mogen overlappen, maar hoeven elkaar niet woord voor woord te herhalen.

Gebruik van time en address

Met het <time>-element geef je een datum die machines kunnen lezen, zoals de datum van publicatie of de laatste aanpassing. Het <address>-element is bedoeld voor contactgegevens van de auteur van het artikel, niet voor elk adres dat toevallig in je tekst staat. Link naar een auteurspagina met nuttige informatie over de auteur en zijn profielen.

Hier is een voorbeeld met <time> en <address>:

html
<p>
  Gepubliceerd op <time datetime="2026-04-14">14 april 2026</time>
</p>
<address>
  Geschreven door <a href="/auteurs/sam-voorbeeld">Sam Voorbeeld</a>.
  Volg Sam op <a href="https://www.linkedin.com/in/sam-voorbeeld/">LinkedIn</a>.
</address>

Schema markup voor blogposts

Schema markup geeft zoekmachines een expliciete beschrijving van je pagina. Voor een blogpost gebruik je het type Article of het specifiekere BlogPosting. Hier is de BlogPosting-markup van het moestuinvoorbeeld:

json
{
  "@context": "https://schema.org",
  "@type": "BlogPosting",
  "headline": "Je eerste moestuin aanleggen",
  "url": "https://www.example.com/blog/eerste-moestuin-aanleggen",
  "image": [
    "https://www.example.com/blog/moestuin-verhoogde-bakken-1x1.jpg",
    "https://www.example.com/blog/moestuin-verhoogde-bakken-4x3.jpg",
    "https://www.example.com/blog/moestuin-verhoogde-bakken-16x9.jpg"
  ],
  "datePublished": "2026-04-14T09:00:00+02:00",
  "dateModified": "2026-06-02T14:30:00+02:00",
  "author": {
    "@type": "Person",
    "name": "Sam Voorbeeld",
    "url": "https://www.example.com/auteurs/sam-voorbeeld",
    "sameAs": ["https://www.linkedin.com/in/sam-voorbeeld/"]
  },
  "publisher": {
    "@type": "Organization",
    "name": "Moestuinblog",
    "url": "https://www.example.com",
    "logo": {
      "@type": "ImageObject",
      "url": "https://www.example.com/logo.png"
    }
  }
}

Google toont sinds 7 mei 2026 geen FAQ-rich-results meer in de zoekresultaten (zie de changelog van Google Search Central). Schrijf dus geen FAQ-markup die alleen voor zoekmachines bestaat. Staat dezelfde FAQ wel zichtbaar op je pagina, dan kun je FAQPage blijven gebruiken. Machines kunnen de vragen en antwoorden dan lezen. Hier is een voorbeeld voor de FAQ onder het moestuinartikel:

json
{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    {
      "@type": "Question",
      "name": "Hoeveel zon heeft een moestuin nodig?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "De meeste groenten hebben minstens zes uur direct zonlicht per dag nodig. Bladgroenten zoals sla verdragen wat meer schaduw."
      }
    },
    {
      "@type": "Question",
      "name": "Wanneer zaai ik in een nieuwe moestuin?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Zaai buiten pas als de grond is opgewarmd, meestal vanaf half april. Gevoelige groenten zoals bonen wachten tot na half mei."
      }
    }
  ]
}

Valideer je markup altijd nadat je hem hebt geplakt:

  1. Test de pagina of de code in de Rich Results Test van Google. Je ziet meteen of Google de ondersteunde structured data herkent.
  2. Controleer de woordenschat met de Schema.org-validator. Die toont ook types die Google niet als rich result gebruikt.
  3. Bekijk de gepubliceerde pagina via URL-inspectie in Google Search Console. Zo zie je hoe Google de pagina echt leest.

Als snelle eigen controle moet de JSON zonder fouten door JSON.parse gaan, zonder HTML-entities zoals &quot; in de tekst. Ook dit artikel staat als BlogPosting in JSON-LD in de paginabron. De inhoudsopgave wordt opgebouwd uit dezelfde h2-koppen die je leest, dus koppen en ankers komen uit één bron. De FAQ hieronder is exact de FAQ in de FAQPage-markup.

Semantische opmaak en AI-crawlers

Net als zoekmachines lezen AI-crawlers de HTML die de server aflevert. Duidelijke koppen en landmarks maken het makkelijker om één passage los van de rest van een pagina te citeren. Structured data beschrijft de pagina, maar garandeert niet dat een AI-antwoord ernaar verwijst.

Conclusie

Met juiste semantische opmaak wordt je artikel duidelijker voor lezers, schermlezers en zoekmachines. Gebruik koppen in de juiste volgorde, zet de blogpost in een <article>, beschrijf informatieve beelden met een bruikbare alt-tekst, zet datums in een <time>-element en voeg geldige schema markup toe die klopt met wat er echt op de pagina staat.

Voor de redactionele kant lees je mijn artikel over de opmaak en structuur van tekst voor een blogpost. MDN heeft daarnaast een handig naslagwerk over semantiek in HTML.

Wil je dit liever aan een professional overlaten? Bij Straffe Sites zijn semantisch correcte HTML en geldige schema markup standaard onderdeel van elk traject. Voor vragen over je eigen blogposts kun je altijd contact met me opnemen.