I’ve gone down into the depths these last couple of weeks with IndieWeb, POSSE and a whole bunch of other arcane terminology. Now that I’ve come up for air, let’s chat about it.

What?

The IndieWeb organisation describe it like this:

The IndieWeb is a community of independent & personal websites connected by simple standards, based on the principles of: owning your domain & using it as your primary identity, publishing on your own site (optionally syndicating elsewhere), and owning your data.

What this actually means in practice, at least for myself, is the following:

  • This website serves as my one canonical identity on the web.
  • Everything gets posted on this website first, and other places (Twitter, Mastodon, etc., often referred to as silos) second. This includes blog posts but also other shortform posts, comparable to tweets/toots, that I’ll refer to as ’notes'.
  • Any responses to posts or notes get fed back to here.

Why?

If the recent Twitter debacle has taught us anything it is that platforms aren’t stable. Tying your online identity to a corporate-owned website is fine for a while but in the very long run anything posted there is, ultimately, ephemeral.

Twitter might, genuinely, disappear in the next few years. Meta-owned platforms are slowly rotting as the algorithmic chum piles up - I need to rescue my photo albums before it’s too late. All the stuff I posted to Bebo as a teenager is irretrievably gone, and while in my personal case this is probably a good thing, the fragility of our online ecosystem is cause for concern.

Even Mastodon suffers from this - while the network itself cannot be meaningfully disrupted by, say, a fash-adjacent billionaire, an individual account might disappear due to a malicious or incompetent instance owner. I run my own instance, so this is less of a cause for concern for me, but I’m still uneasy about it.

The only thing we can really rely on on the web is the web itself. It is ubiquitous enough to be mostly decentralised, has backwards-compatible standards that are mostly agreed-upon, and is mostly resilient to attack by anything other than, like, a nation, or that guy who broke BGP that one time.

It’s still totally cool and desirable to use platforms - that’s where my friends mostly are, after all - but the idea of having my content live here, in a place I fully control, was something I was quite attracted to. Enter IndieWeb, which I first heard about through Jacky Alciné.

How?

I’m not going to try and write a tutorial for getting set up on the IndieWeb because frankly I think it is quite a convoluted process and also because better resources than me exist. I started out with IndieWebify.Me, which is a fantastic resource for learning about what it is as well as the various bits you need to implement.

Some blog platforms, like WordPress, make this process much simpler, but as this website is built as a static site there is some more work to do.

Web Sign In

I like this one a lot. The idea is that if your website is your canonical identity on the web, then it should be the authoritative source for how you log into stuff.

For example, I have various social links on my page - either in the sidebar or footer depending on how you’re reading this - like Twitter, Mastodon and GitHub. By adding a rel=me tag to each of them, I inform any IndieWeb-compatible parsers that these links are to my various identities across the web. Some of those identities are on websites that offer a sign-in flow. This means I can log in to anything that supports Web Sign In by just providing my domain name.

Here’s what my links look like:

<a class="fab fa-github" rel="me" href="https://github.com/JoelOtter"></a>
<a class="fab fa-itch-io" rel="me" href="https://itch.io/joelotter"></a>
<a class="fab fa-mastodon" rel="me" href="https://otter.garden/@joel"></a>
<a class="fab fa-twitter" rel="me" href="https://twitter.com/JoelOtter"></a>

If I log into Webmention.io, a service we’ll be talking about in a minute, I get this:

A screenshot of IndieAuth

There are various services implementing web sign-in, including IndieAuth and RelMeAuth. The IndieWeb wiki has a page on web sign-in, as it does for most things.

Microformats

How do IndieWeb websites talk to each other? They read HTML! In order to tell them exactly how to parse your website, there’s a standard called Microformats.

I’m not going to go into the weeds with how exactly Microformats is used - again, there are better resources than me - but here are the broad steps I took to make my website IndieWeb compatible.

First up, you need a h-card entry describing you and your website. This is just some basic info - you can think of it as a ‘profile’. Mine looks like this:

<div class="h-card">
  <a class="u-url" rel="me" href="https://www.joelotter.com">joelotter.com</a>
  <span class="p-name" rel="me">Joel Auterson</span>
  <span class="p-nickname">JoelOtter</span>
  <img class="u-photo" src="/img/profile.jpg" alt="Joel Auterson" />
  <span class="p-locality">London</span>
</div>

Next up is ensuring your posts are marked up accordingly. I used the various validator tools on IndieWebify.me to get this right. Here’s a small sample (it’s a Go HTML template, hence the weird squiggles).

<div class="hidden">
  <a class="u-url" href="{{ .Permalink }}"></a>
  <time class="dt-published">{{ .Date.Format "2006-01-02T15:04:05Z0700"  }}</time>
  <a rel="author" class="p-author h-card" href="{{ .Site.BaseURL }}">
    Joel Auterson
    <img class="u-photo" src="/img/profile.jpg" alt="Joel Auterson" />
  </a>
  <span class="p-summary">{{ partial "plaintext_summary.html" . }}</span>
</div>

I also added h-feed tags to anything that can be parsed as a feed, like the list of latest posts on the home page. I used the Microformats parser at pin13.net to check I had everything working right.

POSSE

This is the big one, and probably the bit it took me the longest to get to where I want. POSSE stands for “Post on your Own Site, Syndicate Elsewhere”, and it’s how we get from posting on a website to posting on a website and having it go on my Twitter, Mastodon, whatever. There’s also PESOS (you work it out).

To get this working I use a service called brid.gy, which is amazing - essentially it parses your website and works out how to format a tweet or toot. It can also do what’s called “backfeeding”, which we’ll look at in a minute.

brid.gy has really good and comprehensive docs which I recommend. My flow for publishing something now goes like this:

  1. Post it on my website
  2. Wait for it to go online via GitHub Pages
  3. Tell brid.gy about the post, and it’ll publish it to Twitter and Mastodon for me.
  4. Update the post with the Twitter and Mastodon links.

I’ve got my notes set up to link to their syndicated posts. For a basic example, here is a note from last weekend, and its corresponding Mastodon and Twitter posts.

brid.gy is also smart enough to work out what kind of thing it needs to publish to various networks. For example, this note appears on my site as some text and a link, but thanks to the u-repost-of tag brid.gy instead retweeted/boosted the original poster. You can do stuff like replies and quote-tweets too.

I’ve seen some people that run their entire social media from just their website, even doing replies and so on. I haven’t quite got the patience for this due to the static nature of my website and the relative effort it takes to post something, but there are standards out there like Micropub that I could try and implement against if I was so inclined.

Backfeeding

You’ll notice that on my notes and posts you can see comments, likes and reposts. My blog doesn’t have a comment form - all of these come from Twitter and Mastodon, and are backfed to my blog by brid.gy, via a Webmention.

Webmentions are an open standard for the web, and basically are like a sort of cross-site @mention. If you’re old enough to remember pingbacks in the blogosphere days, they’re a sort of non-shit version of that.

To send webmentions, parse a website’s HTML and look for its rel="webmention" link. I have one! It looks like this.

<link rel="webmention" href="https://webmention.io/www.joelotter.com/webmention" />

I don’t currently have an automated setup for sending Webmentions. Instead, I pop my URL into a tool like Telegraph, which looks for Webmention-compatible links on a page and sends them for you. This is the kind of thing I’ll probably set up a GitHub Action to automate on publish.

Receiving Webmentions is a little more complicated. Normally you’d have a server endpoint to receive them at, but I don’t have a server as I’m a static site.

Webmention.io solves this problem nicely. It acts as a public bucket for Webmentions that you can query from your site in JavaScript, then turn that into some layout. I’m not going to show you all my JS code for that because it’s gross, but here’s a little bit showing the relevant part.

fetch("https://webmention.io/api/mentions?token={{ .Site.Params.webmentions.token }}&target=" + {{ .Permalink }}).then(
  response => response.json()
).then(jsonData => {
  let data = {};
  for (const link of jsonData.links) {
    if (!data[link.activity.type]) {
      data[link.activity.type] = [];
    }
    data[link.activity.type].push(link.data);
  }
  return data;
}).then(data => {
  const interactionsDiv = document.getElementById('interactions');
  if (data['repost']) {
    createInteractionGroup(interactionsDiv, "reposts", data.repost, "fa-retweet");
  }

  if (data['like']) {
    createInteractionGroup(interactionsDiv, "likes", data.like, "fa-heart");
  }

  if (data['reply']) {
    createReplyGroup(interactionsDiv, data.reply);
  }
});

What’s next

I’ve got to a point with this stuff where I’m pretty happy with it! The only thing I’d really like to add is some kind of Micropub-compatible setup where I could post notes as easily as I do through a Mastodon app, rather than needing to use Git on my computer.

This post makes IndieWeb stuff look really hard, but I think the majority of the difficulty is self-imposed by me sticking with a static site generator. If you were to run your website on WordPress or something there are plugins to do pretty much all of this for you.

I’ve largely avoided Twitter since Space Karen took over, but this gives me quite a nice way to interact with it while keeping it at arm’s length. I don’t know how long this will last given the changes to their API.

Further reading

  • The IndieWeb wiki is a really fantastic resource
  • IndieWebify.Me is invaluable for getting set up
  • I used this blog post by Christian Engel for reference a lot during my journey through the IndieWeb warren. I’ve kind of inadvertently ended up replicating it. It’s also a great website to reference for formatting and so on!