Indieweb Webmentions on Middleman or Jekyll

Recently, @ttscoff asked a little bit about how I'm including twitter replies to a blog post on my site. I like building and hacking on stuff on my site… so one of my experiments is "joining the indieweb."

There isn't a right way to implement this stuff… one of the beautiful and bewildering things about the indieweb is how open it is… this is just the way that I have it working for now.

What is the Indieweb?

When you post something on the web, it should belong to you, not a corporation. Too many companies have gone out of business and lost all of their users’ data. By joining the IndieWeb, your content stays yours and in your control.

indieweb.org

I've missed the old days of exciting, self-built social networks, web-rings, and such, and as with all new tech… I like the idea of owning my own content, but still being connected and part of a network. I like the idea of not being beholden to some social giant to connect me and steal all my data.

At the moment, indieweb development is a really fun, rowdy, neat group of developers experimenting and connecting mostly on the indieweb wiki and IRC. There is a slack mirror of the IRC if that's your jam.

To learn more, check out indieweb.org or the Getting Started page on the wiki.

Tech Details

My blog uses middleman for static-site generation. I'm sure this process should also work for Jekyll, or any other static websites.

Using a static site means that all you see is sitting as a static file on S3. That means that I don't have a server to respond to queries and requests or do the "thinking" for my website… so for the moment I'm going to have to lean on some others.

I think that other folks like Keith Grant are using webmentions and micropub to make their blog more responsive as they move around the web… I may look into making that work for me. Seems like a fun use case for elixir… but that's later. For now, it's a ruby build script, and some javascript talking to other tools to connect everything. More on that.

While working on getting everything configured correctly, I used several tools to debug my setup. Probably the most helpful was indiewebify.me. I did experience problems with several of the tools because I was compressing files on S3 using gzip and it was interfering somehow with the scraper. Once I turned that off everything went a lot smoother.

Identity: setting up your indieweb profile

When you set up a social network… first you set up your profile. It's the same for the indieweb!

webmention.io

My static site can't respond to anything… so someone else has to do the listening for me. I'm using http://webmention.io after finding it either in a guide or on the wiki.

I first authenticated my site on webmention.io using a twitter link… it uses another service called indielogin.com to identify people by the services they list on their website.

Basically: I can login to twitter. My twitter links to my website and vice versa. If I can log into my twitter, I can oauth and identify me as the person who owns my website. Cool!

The install guide on webmention.io walked me through adding the "pingback URLs"… this means that if someone wants to comment on this website, that's where they should send their webmention.

h-card

I also had provide information about myself on my site. Using microformats on an element classed .h-card, you can describe and specify details. If you send someone a webmention, their service will look at your homepage to find information about you.

Here's the current h-card from my home page:

<div class="h-card  p-author  u-author  hidden">
  <img class="u-photo" src="http://evantravers.com/images/avatar.jpg" alt="">
  <p class="p-note">
    I make tools and tell stories. In love with the grace I have found, and
    finding myself currently in <span class="p-locality">Birmingham, AL</span>.
  </p>
  <a href="http://evantravers.com/" class="u-url  u-uid  p-name" rel="me">Evan Travers</a>
  <a href="mailto:[email protected]" rel="me" class="u-email">[email protected]</a>
</div>

It's pretty simple… it's a structured document with some additional microformat markup to tell other programs how the fields are classified.

At the moment, it's invisible from view, which isn't the best thing to do. The h-card on Jeremy Keith's blog Adactio is a lot classier.

image of the h-card on Adactio.com

You can see the results of my h-card by visiting this microformats parser.

There's a little confusion here… if you read on the microformats wiki, you'll find that there's another format called vcard that you can add for backwards compatibility. There was also debate as to what fields should be included where… There's a lot of change and iteration as people experiment and let experiments die… just part of the indieweb world I guess. The IRC at #indieweb or slack channel is really helpful here.

Connecting the dots

Now someone who scrapes my site can see who I am and what accounts on other sites I'm associated with… and webmention.io is listening on my behalf for any webmentions that might be sent my way… time to start posting and talking!

Listening: Twitter Conversations

For connecting my site to others, I'm using brid.gy.

screenshot of brid.gy's home page

Bridgy connects your web site to social media. Likes, retweets, mentions, cross-posting, and more...

I hooked up my twitter to bridgy, so it's trolling my twitter periodically and sending webmentions for me! The result of this is if I post a tweet containing a link to a page on my website, brid.gy is listening and sends a webmention back to my URL. This even works for replies, likes, and retweets… you can interact with my content on other services, and it all comes back to my personal site.

The indieweb calls this POSSE, for Publish (on your) Own Site, Syndicate Elsewhere.

Ideally… I'll eventually set it up so that some script automatically posts my posts to twitter so that people can interact with it there, but for now I'm syndicating manually.

Broadcasting

Sending webmentions is also a manual process. When I post a blog post, I'll manually run the published URL through the webmention gem. In the future, I plan to include the POSSE syndication to twitter and medium and webmention sending somehow in the build step.

I generate a link post every month of all I read, generated from Instapaper links. Unfortunately I was listing every link as a reply-to using my link-post generator… resulting in several nice blogs getting spamm'd by a giant comment that shouldn't have been sent them. Sorry Jeremy1. :(

I now just list the link which results in a webmention… I haven't had a good reason to use the reply-to verb since I realized I was doing it wrong. Sorry everyone.

Displaying the results

When I got everything hooked up I could navigate to webmention.io, authenticate, and use the API link to manually view the json of replies. Yay! Time to display them.

I wrote a very naive component in Vue.js to get the mentions for a given page and display them at the bottom of the page. Right after I wrote it, the blog post I had written about meeting notes got a few kind likes on twitter (thanks to a retweet from @draftsapp, so you can see all the lovely people who liked my post or made a comment to it by replying to it on twitter.

The js is relatively simple, and looks like this:

import Vue from 'vue';
import Axios from 'axios';

(function() {
  Vue.component('mention-author', {
    props: ['author'],
    template: `
      <span class="webmention__author">
        <a :href="author.url">
          <img v-if="author.photo != ''" :src="author.photo" alt="author.name">
          {{ author.name }}
        </a>
      </span>
    `
  });

  Vue.component('blog-webmention', {
    props: ['mention'],
    template: `
      <div class="blog__webmention">
        <div v-if="mention['wm-property'] == 'like-of'">
          <a :href="mention.url">#</a> 👍'd by <mention-author :author="mention.author"></mention-author>
        </div>
        <div v-if="mention['wm-property'] == 'repost-of'">
          <a :href="mention.url">#</a> 🔁'd by <mention-author :author="mention.author"></mention-author>
        </div>
        <div v-if="mention['wm-property'] == 'bookmark-of'">
          <a :href="mention.url">#</a> 🔖'd by <mention-author :author="mention.author"></mention-author>
        </div>
        <div v-if="mention['wm-property'] == 'in-reply-to'">
          <p>{{ mention.content.text }}</p>
          <a :href="mention.url">#</a> 💬'd to by <mention-author :author="mention.author"></mention-author>
        </div>
      </div>
    `
  });

  var webmentions = new Vue({
    el: '#webmentions',
    data: {
      mentions: []
    },
    mounted: function() {
      Axios.get("https://webmention.io/api/links.jf2?target=" + window.location.href)
        .then(response => this.mentions = response.data.children);
    }
  });
})();

Nothing terribly clever here… there's some associated css that styles the avatars and such, but other than that, that's it. I've been meaning to package it up as a web component on NPM, but I have not made the time.

Where to now?

Automate syndication and webmentioning

I mentioned it earlier, but it seems like the obvious step so that I don't forget anything when I'm posting. It's what automation is for.

Caching webmentions

I'd like to pull down all my webmentions from webmention.io on a static build… cache it in a file and have the js show only the new ones. Hopefully that'll reduce the load on webmention.io and I like the idea of being able to keep those comments and likes in my filesystem.

Comment directly on the site

I think it'd be nice to have a way for people to authenticate and comment right on the site… no clue how to do that yet, but I'm sure someone in the indieweb network is working on it.

It's fun!

I will say… all this is the most fun I've had learning and messing around on my site in a long time. It's fun to figure out, nice people to learn from, and it feels like a tiny step towards a healthier me and healthier web ecosystem.

References:


  1. I'm sorry Jeremy Keith. I really didn't mean to do this


🔖
Changelog
  • 2022-06-08 11:31:29 -0500
    Rename articles

  • 2022-05-03 14:17:29 -0500
    Fix typo

  • 2022-02-08 13:48:30 -0600
    Update syntax highlighting

  • 2020-06-18 14:26:02 -0500
    Move everything to CST

    Don't know why I didn't do that before. It caused _no_ end of
    problems.

  • 2019-11-14 19:21:38 -0600
    Remove Tag: programming

    `code` is the same tag and has more coverage.

  • 2019-11-13 19:01:36 -0600
    Fix typo: "@getdrafts" -> "@draftsapp"

  • 2019-11-13 18:58:23 -0600
    New post: Indieweb mentions on middleman or jekyll