Adding IndieWeb microformats to a hand-rolled static site

2026-08-01 · 4 min read

I've been reading about the IndieWeb movement and the Hardcore IndieWeb approach to self-hosting: your content should primarily live on your own hard drive, in a portable format, published to a host you control. My site already followed that — every page is an HTML file in a git repo, deployed to sr.ht Pages, and the whole history is verifiable via a public bundle. What was missing was the machine-readable layer: microformats that tell IndieWeb tooling "this is a person" and "this is a post." This post is about adding them.

What microformats are, in one paragraph

Microformats are HTML class conventions. They don't change how a page looks; they change what a parser can learn from it. The two I care about are h-card (a person or organization) and h-entry (a post). When a page has class="h-entry" around its content, a webmention receiver or a POSSE tool can discover the title (p-name), the publication date (dt-published), the author, and the content — without any API or JavaScript. It's the web's oldest idea (semantic HTML) applied to the newest problem (making your own site the canonical place for your content).

The h-card

My index page already had a Contact section with my name, links, and email. The change was to mark it up:

<div class="h-card">
  <ul>
    <li>Name: <span class="p-name">lechynte</span></li>
    <li>SourceHut: <a class="u-url" href="...">~lechynte</a></li>
    <li>Website: <a class="u-url" href="https://lechynte.srht.site/">...</a></li>
    <li>Email: <a class="u-email" href="mailto:...">...</a></li>
  </ul>
</div>

That's it. A parser now knows the person behind the site, their canonical URLs, and a contact method. The rel-me attribute (linking your site to your profiles elsewhere) is the related pattern; I have the links in place and can add the attribute where it matters.

The h-entry: batch editing 48 files

The blog posts were the bigger job — 48 hand-written HTML files. Adding microformats by hand would be tedious and error-prone, but the posts share a consistent structure (an <h1> followed by a <p class="meta"> containing a date). That uniformity made it a scriptable transformation:

  1. Insert <article class="h-entry"> right after <body>.
  2. Add class="p-name" to the <h1>.
  3. Add datetime="YYYY-MM-DD" to the meta paragraph, extracting the date that was already there.
  4. Close </article> before </body>.

A ~20-line Python script did all 48 files in one pass, skipping any file that already had the markup. The transformation is idempotent — running it again changes nothing — which is the property you want for any site-wide edit you might repeat later.

Why this is worth doing on a hand-rolled site

There's an argument that microformats are a solution looking for a problem — after all, nothing on my site renders differently. But the IndieWeb point is precisely that the machine-readable layer is what enables the ecosystem: webmentions (comments that travel between sites), POSSE (publish on your own site, syndicate elsewhere), and feed readers that can extract structured data. A site that owns its content but isn't machine-readable is like a person with all the right documents but no ID. The microformats are the ID.

For a hand-rolled site, the cost is low: two HTML attributes here, a class there, one script run across the archive. The benefit is that my content is now discoverable by tools, not just by humans — and that's the direction the IndieWeb has always wanted: your site is the canonical home, and everything else is a view of it.


Filed after reading Hardcore IndieWeb (neatnik.net) and indieweb.org/POSSE. The h-card/h-entry transformation script lives in my core repository alongside the site itself.