TL;DR — If you link to your Mastodon profile from CodePen, and your CodePen profile from Mastodon, your Mastodon profile will display your CodePen profile as a verified link, proving ownership.

How does that work? It’s just HTML!

There is a rel attribute that can go on anchor (<a>) links. The values for rel have a variety of functionality. For example, you can tell search engines not to follow or rank a link and that it is user-generated:

<a 
  href="https://user-generated.com" 
  rel="nofollow ugc">
    User Link
</a>

There are safety and performance-gaining possibilities for using values like noreferrer and noopener as well.

Here’s another value: rel="me" (you can space-separate multiple values). The me value is a rather old-school Microformats thing. It’s pretty neat! The purpose is that you put it on links that point to other things that you own or control. Then, if the link you’re pointing to points directly back also with a rel="me" link that is a verification-of-ownership situation. As the wiki puts it:

Thus establishing a bi-directional rel-me link and confirming that the two URLs represent the same person.

The federated social networking site Mastodon (here’s me!) uses this exact setup to verify personal links. Here’s an image of my Mastodon profile:

Notice there are three links, the first two of which are highlighted with checkmarks and green:

Those “verified” links are verified because they follow the bi-directional rel="me" linking exactly as Mastodon requires.

On CodePen, we’re now adding that me value to all the links you add to your profile. Mastodon does the same, and thus verification is achieved. On my third link, that link to Amazon.com (obviously) doesn’t contain a link back to my Mastodon profile, so it doesn’t verify.

The Other Possible HTML to Verify

While CodePen is now properly putting the me value on profile URLs — that actually didn’t work for Mastodon verification on our first attempt. There were actually two problems:

  • CodePen profiles are client-side rendered, and the Mastodon crawler can only see server-side rendered HTML.
  • We needed to ensure the Mastodon crawler didn’t get trapped by the firewall.

With that second one taken care of via DevOps magic, we still needed a way to make sure the server-rendered HTML had something to verify against.

We aren’t yet server-rendering most of our React-rendered pages (we’ll get there), so the HTML that comes across that first request (and what Mastodon crawls) is essentially a shell page with minimal HTML. We could have tossed the <a rel="me" ...> links into the <body> of that first response, but that seems a little awkward to only have them ripped away by client-side rendering immediately. Instead, there is another equally valid way to provide rel="me" links, and that’s like this:

<head>
  <link rel="me" href="https://chriscoyier.net/">
  <link rel="me" href="https://front-end.social/@chriscoyier">

So we’re actually doing both the <head> links and the <a> links now, and good news, it works great.


Thanks to Will Boyd for asking about this and Amelia Bellamy-Royds for all the back-and-forth on Mastodon as we figured all this out.


Related writings: