Tags: rel

136

sparkline

Friday, October 4th, 2019

Why Progressive Web Apps Are The Future of Mobile Web [2019 Research]

PWAs just work better than your typical mobile site. Period.

But bear in mind:

Maybe simply because the “A” in PWA stands for “app,” too much discussion around PWAs focuses on comparing and contrasting to native mobile applications. We believe this comparison (and the accompanying discussion) is misguided.

Thursday, August 1st, 2019

Navigation preloads in service workers

There’s a feature in service workers called navigation preloads. It’s relatively recent, so it isn’t supported in every browser, but it’s still well worth using.

Here’s the problem it solves…

If someone makes a return visit to your site, and the service worker you installed on their machine isn’t active yet, the service worker boots up, and then executes its instructions. If those instructions say “fetch the page from the network”, then you’re basically telling the browser to do what it would’ve done anyway if there were no service worker installed. The only difference is that there’s been a slight delay because the service worker had to boot up first.

  1. The service worker activates.
  2. The service worker fetches the file.
  3. The service worker does something with the response.

It’s not a massive performance hit, but it’s still a bit annoying. It would be better if the service worker could boot up and still be requesting the page at the same time, like it would do if no service worker were present. That’s where navigation preloads come in.

  1. The service worker activates while simultaneously requesting the file.
  2. The service worker does something with the response.

Navigation preloads—like the name suggests—are only initiated when someone navigates to a URL on your site, either by following a link, or a bookmark, or by typing a URL directly into a browser. Navigation preloads don’t apply to requests made by a web page for things like images, style sheets, and scripts. By the time a request is made for one of those, the service worker is already up and running.

To enable navigation preloads, call the enable() method on registration.navigationPreload during the activate event in your service worker script. But first do a little feature detection to make sure registration.navigationPreload exists in this browser:

if (registration.navigationPreload) {
  addEventListener('activate', activateEvent => {
    activateEvent.waitUntil(
      registration.navigationPreload.enable()
    );
  });
}

If you’ve already got event listeners on the activate event, that’s absolutely fine: addEventListener isn’t exclusive—you can use it to assign multiple tasks to the same event.

Now you need to make use of navigation preloads when you’re responding to fetch events. So if your strategy is to look in the cache first, there’s probably no point enabling navigation preloads. But if your default strategy is to fetch a page from the network, this will help.

Let’s say your current strategy for handling page requests looks like this:

addEventListener('fetch', fetchEvent => {
  const request = fetchEvent.request;
  if (request.headers.get('Accept').includes('text/html')) {
    fetchEvent.respondWith(
      fetch(request)
      .then( responseFromFetch => {
        // maybe cache this response for later here.
        return responseFromFetch;
      })
      .catch( fetchError => {
        return caches.match(request)
        .then( responseFromCache => {
          return responseFromCache || caches.match('/offline');
        });
      })
    );
  }
});

That’s a fairly standard strategy: try the network first; if that doesn’t work, try the cache; as a last resort, show an offline page.

It’s that first step (“try the network first”) that can benefit from navigation preloads. If a preload request is already in flight, you’ll want to use that instead of firing off a new fetch request. Otherwise you’re making two requests for the same file.

To find out if a preload request is underway, you can check for the existence of the preloadResponse promise, which will be made available as a property of the fetch event you’re handling:

fetchEvent.preloadResponse

If that exists, you’ll want to use it instead of fetch(request).

if (fetchEvent.preloadResponse) {
  // do something with fetchEvent.preloadResponse
} else {
  // do something with fetch(request)
}

You could structure your code like this:

addEventListener('fetch', fetchEvent => {
  const request = fetchEvent.request;
  if (request.headers.get('Accept').includes('text/html')) {
    if (fetchEvent.preloadResponse) {
      fetchEvent.respondWith(
        fetchEvent.preloadResponse
        .then( responseFromPreload => {
          // maybe cache this response for later here.
          return responseFromPreload;
        })
        .catch( preloadError => {
          return caches.match(request)
          .then( responseFromCache => {
            return responseFromCache || caches.match('/offline');
          });
        })
      );
    } else {
      fetchEvent.respondWith(
        fetch(request)
        .then( responseFromFetch => {
          // maybe cache this response for later here.
          return responseFromFetch;
        })
        .catch( fetchError => {
          return caches.match(request)
          .then( responseFromCache => {
            return responseFromCache || caches.match('/offline');
          });
        })
      );
    }
  }
});

But that’s not very DRY. Your logic is identical, regardless of whether the response is coming from fetch(request) or from fetchEvent.preloadResponse. It would be better if you could minimise the amount of duplication.

One way of doing that is to abstract away the promise you’re going to use into a variable. Let’s call it retrieve. If a preload is underway, we’ll assign it to that variable:

let retrieve;
if (fetchEvent.preloadResponse) {
  retrieve = fetchEvent.preloadResponse;
}

If there is no preload happening (or this browser doesn’t support it), assign a regular fetch request to the retrieve variable:

let retrieve;
if (fetchEvent.preloadResponse) {
  retrieve = fetchEvent.preloadResponse;
} else {
  retrieve = fetch(request);
}

If you like, you can squash that into a ternary operator:

const retrieve = fetchEvent.preloadResponse ? fetchEvent.preloadResponse : fetch(request);

Use whichever syntax you find more readable.

Now you can apply the same logic, regardless of whether retrieve is a preload navigation or a fetch request:

addEventListener('fetch', fetchEvent => {
  const request = fetchEvent.request;
  if (request.headers.get('Accept').includes('text/html')) {
    const retrieve = fetchEvent.preloadResponse ? fetchEvent.preloadResponse : fetch(request);
    fetchEvent.respondWith(
      retrieve
      .then( responseFromRetrieve => {
        // maybe cache this response for later here.
       return responseFromRetrieve;
      })
      .catch( fetchError => {
        return caches.match(request)
        .then( responseFromCache => {
          return responseFromCache || caches.match('/offline');
        });
      })
    );
  }
});

I think that’s the least invasive way to update your existing service worker script to take advantage of navigation preloads.

Like I said, preload navigations can give a bit of a performance boost if you’re using a network-first strategy. That’s what I’m doing here on adactio.com and on thesession.org so I’ve updated their service workers to take advantage of navigation preloads. But on Resilient Web Design, which uses a cache-first strategy, there wouldn’t be much point enabling navigation preloads.

Jeff Posnick made this point in his write-up of bringing service workers to Google search:

Adding a service worker to your web app means inserting an additional piece of JavaScript that needs to be loaded and executed before your web app gets responses to its requests. If those responses end up coming from a local cache rather than from the network, then the overhead of running the service worker is usually negligible in comparison to the performance win from going cache-first. But if you know that your service worker always has to consult the network when handling navigation requests, using navigation preload is a crucial performance win.

Oh, and those browsers that don’t yet support navigation preloads? No problem. It’s a progressive enhancement. Everything still works just like it did before. And having a service worker on your site in the first place is itself a progressive enhancement. So enabling navigation preloads is like a progressive enhancement within a progressive enhancement. It’s progressive enhancements all the way down!

By the way, if all of this service worker stuff sounds like gibberish, but you wish you understood it, I think my book, Going Offline, will prove quite valuable.

Sunday, July 21st, 2019

The Simplest Way to Load CSS Asynchronously | Filament Group, Inc.

Scott re-examines the browser support for loading everything-but-the-critical-CSS asynchronously and finds that it might now be as straightforward as this one declaration:

<link rel="stylesheet" href="/path/to/my.css" media="print" onload="this.media='all'">

I love the fact the Filament Group are actively looking at how deprecate their loadCSS polyfill—exactly the right attitude for polyfills in general.

Tuesday, July 16th, 2019

Trad time

Fifteen years ago, I went to the Willie Clancy Summer School in Miltown Malbay:

I’m back from the west of Ireland. I was sorry to leave. I had a wonderful, music-filled time.

I’m not sure why it took me a decade and a half to go back, but that’s what I did last week. Myself and Jessica once again immersed ourselves in Irish tradtional music. I’ve written up a trip report over on The Session.

On the face of it, fifteen years is a long time. Last time I made the trip to county Clare, I was taking pictures on a point-and-shoot camera. I had a phone with me, but it had a T9 keyboard that I could use for texting and not much else. Also, my hair wasn’t grey.

But in some ways, fifteen years feels like the blink of an eye.

I spent my mornings at the Willie Clancy Summer School immersed in the history of Irish traditional music, with Paddy Glackin as a guide. We were discussing tradition and change in generational timescales. There was plenty of talk about technology, but we were as likely to discuss the influence of the phonograph as the influence of the internet.

Outside of the classes, there was a real feeling of lengthy timescales too. On any given day, I would find myself listening to pre-teen musicians at one point, and septegenarian masters at another.

Now that I’m back in the Clearleft studio, I’m finding it weird to adjust back in to the shorter timescales of working on the web. Progress is measured in weeks and months. Technologies are deemed outdated after just a year or two.

The one bridging point I have between these two worlds is The Session. It’s been going in one form or another for over twenty years. And while it’s very much on and of the web, it also taps into a longer tradition. Over time it has become an enormous repository of tunes, for which I feel a great sense of responsibility …but in a good way. It’s not something I take lightly. It’s also something that gives me great satisfaction, in a way that’s hard to achieve in the rapidly moving world of the web. It’s somewhat comparable to the feelings I have for my own website, where I’ve been writing for eighteen years. But whereas adactio.com is very much focused on me, thesession.org is much more of a community endeavour.

I question sometimes whether The Session is helping or hindering the Irish music tradition. “It all helps”, Paddy Glackin told me. And I have to admit, it was very gratifying to meet other musicians during Willie Clancy week who told me how much the site benefits them.

I think I benefit from The Session more than anyone though. It keeps me grounded. It gives me a perspective that I don’t think I’d otherwise get. And in a time when it feels entirely to right to question whether the internet is even providing a net gain to our world, I take comfort in being part of a project that I think uses the very best attributes of the World Wide Web.

Monday, July 15th, 2019

Spurious Correlations

Correlation does not imply causation.

Tuesday, May 28th, 2019

How Ireland became Europe’s data watchdog - BBC News

The coming GDPR storm:

Ireland’s Data Protection Commissioner, Helen Dixon, is expected to circulate her decisions on some cases by July or August, with final rulings made by the end of the year.

(That’s my sister-in-law, that is.)

Wednesday, April 24th, 2019

Preload, prefetch and other link tags: what they do and when to use them · PerfPerfPerf

Following on from Harry’s slides, here’s another round-up of thoserel attribute values that begin with pre.

More Than You Ever Wanted to Know About Resource Hints - Speaker Deck

Slides from Harry’s deep dive into rel values: preconnect, prefetch, and preload.

Wednesday, December 19th, 2018

Performance Calendar » All about prefetching

A good roundup of techniques for responsible prefetching from Katie Hempenius.

Monday, December 3rd, 2018

Voxxed Thessaloniki 2018 - Opening Keynote - Taking Back The Web - YouTube

Here’s the talk I gave recently about indie web building blocks.

There’s fifteen minutes of Q&A starting around the 35 minute mark. People asked some great questions!

Tuesday, November 6th, 2018

How to get on the #indieweb!

As well as graciously hosting Indie Web Camp Berlin on the weekend at Mozilla’s offices, Yulia has also drawn this super-cute comic.

Wednesday, September 5th, 2018

The Font Loading Checklist—zachleat.com

This checklist came in very handy during a performance-related workshop I was running today (I may have said the sentence “Always ask yourself What Would Zach Do?”).

  1. Start Important Font Downloads Earlier (Start a Web Font load)
  2. Prioritize Readable Text (Behavior while a Web Font is loading)
  3. Make Fonts Smaller (Reduce Web Font load time)
  4. Reduce Movement during Page Load (Behavior after a Web Font has loaded)

The first two are really straightforward to implement (with rel="preload" and font-display). The second two take more work (with subsetting and the font loading API).

Friday, August 10th, 2018

“Designer + Developer Workflow,” an article by Dan Mall

Dan compares the relationship between a designer and developer in the web world to the relationship between an art director and a copywriter in the ad world. He and Brad made a video to demonstrate how they collaborate.

Tuesday, July 10th, 2018

Ways to think about machine learning — Benedict Evans

This strikes me as a sensible way of thinking about machine learning: it’s like when we got relational databases—suddenly we could do more, quicker, and easier …but it doesn’t require us to treat the technology like it’s magic.

An important parallel here is that though relational databases had economy of scale effects, there were limited network or ‘winner takes all’ effects. The database being used by company A doesn’t get better if company B buys the same database software from the same vendor: Safeway’s database doesn’t get better if Caterpillar buys the same one. Much the same actually applies to machine learning: machine learning is all about data, but data is highly specific to particular applications. More handwriting data will make a handwriting recognizer better, and more gas turbine data will make a system that predicts failures in gas turbines better, but the one doesn’t help with the other. Data isn’t fungible.

Sunday, July 1st, 2018

Keynote: The Building Blocks Of The Indie Web - YouTube

Here’s the video of the talk I gave at Design4Drupal last week in Boston. There’s a good half an hour of questions at the end.

Friday, June 8th, 2018

Registering service workers

In chapter two of Going Offline, I talk about registering your service worker wrapped up in some feature detection:

But I also make reference to a declarative way of doing this that isn’t very widely supported:


No need for feature detection there. Thanks to the liberal error-handling model of HTML (and CSS), browsers will just ignore what they don’t understand, which isn’t the case with JavaScript.

Alas, it looks like that nice declarative alternative isn’t going to be making its way into browsers anytime soon. It has been removed from the HTML spec. That’s a shame. I have a preference for declarative solutions where possible—they’re certainly easier to teach. But in this case, the JavaScript alternative isn’t too onerous.

So if you’re reading Going Offline, when you get to the bit about someday using the rel value, you can cast a wistful gaze into the distance, or shed a tiny tear for what might have been …and then put it out of your mind and carry on reading.

Thursday, May 17th, 2018

New Privacy Rules Could Make This Woman One of Tech’s Most Important Regulators - The New York Times

It’s kind of surreal to see a profile in the New York Times of my sister-in-law. Then again, she is Ireland’s data protection commissioner, and what with Facebook, Twitter, and Google all being based in Ireland, and with GDPR looming, her work is more important than ever.

By the way, this article has 26 tracking scripts. I don’t recall providing consent for any of them.

Monday, May 14th, 2018

Taking Back The Web

This presentation on the indie web was delivered as the opening keynote at Webstock in Wellington, Zealand in February 2018.

Thank you. Thank you very much, Mike; it really is an honour and a privilege to be here. Kia Ora! Good morning.

This is quite intimidating. I’m supposed to open the show and there’s all these amazing, exciting speakers are going to be speaking for the next two days on amazing, exciting topics, so I’d better level up: I’d better talk about something exciting. So, let’s do it!

Economics

Yeah, we need to talk about capitalism. Capitalism is one of a few competing theories on how to structure an economy and the theory goes that you have a marketplace and the marketplace rules all and it is the marketplace that self-regulates through its kind of invisible hand. Pretty good theory, the idea being that through this invisible hand in the marketplace, wealth can be distributed relatively evenly; sort of a bell-curve distribution of wealth where some people have more, some people have less, but it kind of evens out. You see bell-curve distributions right for things like height and weight or IQ. Some have more, some have less, but the difference isn’t huge. That’s the idea, that economies could follow this bell-curve distribution.

A graph showing a bell-curve distribution.

But, without any kind of external regulation, what tends to happen in a capitalistic economy is that the rich get richer, the poor get poorer and it runs out of control. Instead of a bell-curve distribution you end up with something like this which is a power-law distribution, where you have the wealth concentrated in a small percentage and there’s a long tail of poverty.

A graph showing a power-law distribution.

That’s the thing about capitalism: it sounds great in theory, but not so good in practice.

Monopoly

The theory, I actually agree with, the theory being that competition is good and that competition is healthy. I think that’s a sound theory. I like competition: I think there should be a marketplace of competition, to try and avoid these kind of monopolies or duopolies that you get in these power-law distributions. The reason I say that is that we as web designers and web developers, we’ve seen what happens when monopolies kick in.

The icon for Microsoft Internet Explorer.

We were there: we were there when there was a monopoly; when Microsoft had an enormous share of the browser market, it was like in the high nineties, percentage of browser share with Internet Explorer, which they achieved because they had an enormous monopoly in the desktop market as well, they were able to bundle Internet Explorer with the Windows Operating System. Not exactly an invisible hand regulating there.

But we managed to dodge this bullet. I firmly believe that the more browsers we have, the better. I think a diversity of browsers is a really good thing. I know sometimes as developers, “Oh wouldn’t it be great if there was just one browser to develop for: wouldn’t that be great?” No. No it would not! We’ve been there and it wasn’t pretty. Firefox was pretty much a direct result of this monopoly situation in browsers. But like I say, we dodged this bullet. In some ways the web interpreted this monopoly as damage and routed around it. This idea of interpreting something as damaged and routing around it, that’s a phrase that comes from network architecture

Networks

As with economies, there are competing schools of thought on how you would structure a network; there’s many ways to structure a network.

A ring of small circles, each one connected to a larger circle in the middle.

One way, sort of a centralised network approach is, you have this hub and spoke model, where you have lots of smaller nodes connecting to a single large hub and then those large hubs can connect with one another and this is how the telegraph worked, then the telephone system worked like this. Airports still pretty much work like this. You’ve got regional airports connecting to a large hub and those large hubs connect to one another, and it’s a really good system. It works really well until the hub gets taken out. If the hub goes down, you’ve got these nodes that are stranded: they can’t connect to one another. That’s a single point of failure, that’s a vulnerability in this network architecture.

A circle of  small circles, with no connections between them.

It was the single point of failure, this vulnerability, that led to the idea of packet-switching and different network architectures that we saw in the ARPANET, which later became the Internet. The impetus there was to avoid the single point of failure. What if you took these nodes and gave them all some connections?

A scattering of circles, each one with some connections to other circles.

This is more like a bell-curve distribution of connections now. Some nodes have more connections than others, some have fewer, but there isn’t a huge difference between the amount of connections between nodes. Then the genius of packet-switching is that you just need to get the signal across the network by whatever route works best at the time. That way, if a node were to disappear, even a relatively well-connected one, you can route around the damage. Now you’re avoiding the single point of failure problem that you would have with a hub and spoke model.

The same scattering of circles, with one of them removed. The other circles are still connected.

Like I said, this kind of thinking came from the ARPANET, later the Internet and it was as a direct result of trying to avoid having that single point of failure in a command-and-control structure. If you’re in a military organisation, you don’t want to have that single point of failure. You’ve probably heard that the internet was created to withstand a nuclear attack and that’s not exactly the truth but the network architecture that we have today on the internet was influenced by avoiding that command-and-control, that centralised command-and-control structure.

Some people kind of think there’s sort of blood on the hands of the internet because it came from this military background, DARPA…Defence Advance Research Project. But actually, the thinking behind this was not to give one side the upper hand in case of a nuclear conflict: quite the opposite. The understanding was, if there were the chance of a nuclear conflict and you had a hub and spoke model of communication, then actually you know that if they take out your hub, you’re screwed, so you’d better strike first. Whereas if you’ve got this kind of distributed network, then if there’s the possibility of attack, you might be more willing to wait it out and see because you know you can survive that initial first strike. And so this network approach was not designed to give any one side the upper hand in case of a nuclear war, but to actually avoid nuclear war in the first place. On the understanding that this was in place for both sides, so Paul Baran and the other people working on the ARPANET, they were in favour of sharing this technology with the Russians, even at the height of the Cold War.

The World Wide Web

In this kind of network architecture, there’s no hubs, there’s no regional nodes, there’s just nodes on the network. It’s very egalitarian and the network can grow and shrink infinitely; it’s scale-free, you can just keep adding nodes to network and you don’t need to ask permission to add a node to this network. That same sort of architecture then influenced the World Wide Web, which is built on top of the Internet and Tim Berners-Lee uses this model where anybody can add a website to the World Wide Web: you don’t need to ask for permission, you just add one more node to the network; there’s no plan to it, there’s no structure and so it’s a mess! It’s a sprawling, beautiful mess with no structure.

Walled Gardens

And it’s funny, because in the early days of the Web it wasn’t clear that the Web was going to win; not at all. There was competition. You had services like Compuserve and AOL. I’m not talking about AOL the website. Before it was a website, it was this thing separate to the web, which was much more structured, much safer; these were kind of the walled gardens and they would make wonderful content for you and warn you if you tried to step outside the bounds of their walled gardens into the wild, lawless lands of the World Wide Web and say, ooh, you don’t want to go out there. And yet the World Wide Web won, despite its chaoticness, its lawlessness. People chose the Web and despite all the content that Compuserve and AOL and these other walled gardens were producing, they couldn’t compete with the wild and lawless nature of the Web. People left the walled gardens and went out into the Web.

And then a few years later, everyone went back into the walled gardens. Facebook, Twitter, Medium. Very similar in a way to AOL and Compuserve: the nice, well-designed places, safe spaces not like those nasty places out in the World Wide Web and they warn you if you’re about to head out into the World Wide Web. But there’s a difference this time round: AOL and Compuserve, they were producing content for us, to keep us in the walled gardens. With the case of Facebook, Medium, Twitter, we produce the content. These are the biggest media companies in the world and they don’t produce any media. We produce the media for them.

How did this happen? How did we end up with this situation when we returned into the walled gardens? What happened?

Facebook, I used to wonder, what is the point of Facebook? I mean this in the sense that when Facebook came along, there were lots of different social networks, but they all kinda had this idea of being about a single, social object. Flickr was about the photograph and upcoming.org was about the event and Dopplr was about travel. And somebody was telling me about Facebook and saying, “You should get on Facebook.” I was like, “Oh yeah? What’s it for?” He said: “Everyone’s on it.” “Yeah, but…what’s it for? Is it photographs, events, what is it?” And he was like, “Everyone’s on it.” And now I understand that it’s absolutely correct: the reason why everyone is on Facebook is because everyone is on Facebook. It’s a direct example of Metcalfe’s Law.

The icon for Facebook, superimposed on a graph showing a power-law distribution.

Again, it’s a power-law distribution: that the value of the network is proportional to the square of the number of nodes on a network. Basically, the more people on the network the better. The first person to have a fax machine, that’s a useless lump of plastic. As soon as one more person has a fax machine, it’s exponentially more useful. Everyone is on Facebook because everyone is on Facebook. Which turns it into a hub. It is now a centralised hub, which means it is a single point of failure, by the way. In security terms, I guess you would talk about it having a large attack surface.

Let’s say you wanted to attack media outlets, I don’t know, let’s say you were trying to influence an election in the United States of America… Instead of having to target hundreds of different news outlets, you now only need to target one because it has a very large attack surface.

It’s just like, if you run WordPress as a CMS, you have to make sure to keep it patched all the time because it’s a large attack surface. It’s not that it’s any more or less secure or vulnerable than any other CMS, it’s just that it’s really popular and therefore is more likely to be attacked. Same with a hub like Facebook.

OK. Why then? Why did we choose to return to these walled gardens? Well, the answer’s actually pretty obvious, which is: they’re convenient. Walled gardens are nice to use. The user experience is pretty great; they’re well-designed, they’re nice.

The disadvantage is what you give up when you gain this convenience. You give up control. You no longer have control over the content that you publish. You don’t control who’s going to even see what you publish. Some algorithm is taking care of that. These silos—Facebook, Twitter, Medium—they now have control of the hyperlinks. Walled gardens give you convenience, but the cost is control.

The Indie Web

This is where this idea of the indie web comes in, to try and bridge this gap that you could somehow still have the convenience of using these beautiful, well-designed walled gardens and yet still have the control of owning your own content, because let’s face it, having your own website, that’s a hassle: it’s hard work, certainly compared to just opening up Facebook, opening a Facebook account, Twitter account, Medium account and just publishing, boom. The barrier to entry is really low whereas setting up your own website, registering a domain, do you choose a CMS? There’s a lot of hassle involved in that.

But maybe we can bridge the gap. Maybe we can get both: the convenience and the control. This is the idea of the indie web. At its heart, there’s a fairly uncontroversial idea here, which is that you should have your own website. I mean, there would have been a time when that would’ve been a normal statement to make and these days, it sounds positively disruptive to even suggest that you should have your own website.

Longevity

I have my own personal reasons for wanting to publish on my own website. If anybody was here back in the…six years ago, I was here at Webstock which was a great honour and I was talking about digital preservation and longevity and for me, that’s one of the reasons why I like to have the control over my own content, because these things do go away. If you published your content on, say, MySpace: I’m sorry. It’s gone. And there was a time when it was unimaginable that MySpace could be gone; it was like Facebook, you couldn’t imagine the web without it. Give it enough time. MySpace is just one example, there’s many more. I used to publish in GeoCities. Delicious; Magnolia, Pownce, Dopplr. Many, many more.

Now, I’m not saying that everything should be online for ever. What I’m saying is, it should be your choice. You should be able to choose when something stays online and you should be able to choose when something gets taken offline. The web has a real issue with things being taken offline. Linkrot is a real problem on the web, and partly that’s to do with the nature of the web, the fundamental nature of the way that linking works on the web.

Hyperlinks

When Tim Berners-Lee and Robert Cailliau were first coming up with the World Wide Web, they submitted a paper to a hypertext conference, I think it was 1991, 92, about this project they were building called the World Wide Web. The paper was rejected. Their paper was rejected by these hypertext experts who said, this system: it’ll never work, it’s terrible. One of the reasons why they rejected it was it didn’t have this idea of two-way linking. Any decent hypertext system, they said, has a concept of two-way linking where there’s knowledge of the link at both ends, so in a system that has two-way linking, if a resource happens to move, the link can move with it and the link is maintained. Now that’s not the way the web works. The web has one-way linking; you can just link to something, that’s it and the other resource has no knowledge that you’re linking to it but if that resource moves or goes away, the link is broken. You get linkrot. That’s just the way the web works.

But. There’s a little technique that if you sort of squint at it just the right way, it sort of looks like two-way linking on the web and involves a very humble bit of HTML. The rel attribute. Now, you’ve probably seen the rel attribute before, you’ve probably seen it on the link element. Rel is short for relationship, so the value of the rel attribute will describe the relationship of the linked resource, whatever’s inside the href; so I’m sure you’ve probably typed this at some point where you say rel=stylesheet on a link element. What you’re saying is, the linked resource, what’s in the href, has the relationship of being a style sheet for the current document.

link rel="stylesheet" href="..."

You can use it on A elements as well. There’s rel values like prev for previous and next, say this is the relationship of being the next document, or this is the relationship of being the previous document. Really handy for pagination of search results, for example.

a rel="prev" href="..."
a rel="next" href="..."

And then there’s this really silly value, rel=me.

a rel="me" href="..."

Now, how does that work? The linked document has a relationship of being me? Well, I use this. I use this on my own website. I have A elements that link off to my profiles on these other sites, so I’m saying, that Twitter profile over there: that’s me. And that’s me on Flickr and that’s me on GitHub.

a rel="me" href="https://twitter.com/adactio"
a rel="me" href="https://flickr.com/adactio"
a rel="me" href="https://github.com/adactio"

OK, but still, these are just regular, one-way hyperlinks I’m making. I’ve added a rel value of “me” but so what?

Well, the interesting thing is, if you go to any of those profiles, when you’re signing up, you can add your own website: that’s one of the fields. There’s a link from that profile to your own website and in that link, they also use rel=me.

a rel="me" href="https://adactio.com"

I’m linking to my profile on Twitter saying, rel=me; that’s me. And my Twitter profile is linking to my website saying, rel=me; that’s me. And so you’ve kind of got two-way linking. You’ve got this confirmed relationship, these claims have been verified. Fine, but what can you do with that?

RelMeAuth

Well, there’s a technology called RelMeAuth that uses this, kind of piggy-backs on something that all these services have in common: Twitter and Flickr and GitHub. All of these services have OAuth, authentication. Now, if I wanted to build an API, I should probably, for a right-API, I probably need to be an OAuth provider. I am not smart enough to become an OAuth provider; that sounds way too much like hard work for me. But I don’t need to because Twitter and Flickr and GitHub are already OAuth providers, so I can just piggy-back on the functionality that they provide, just be adding rel=me.

Here’s an example of this in action. There’s an authentication service called IndieAuth and I literally sign in with my URL. I type in my website name, it then finds the rel=me links, the ones that are reciprocal; I choose which one I feel like logging in with today, let’s say Twitter, I get bounced to Twitter, I have to be logged in on Twitter for this to work and then I’ve authenticated. I’ve authenticated with my own website; I’ve used OAuth without having to write OAuth, just by adding rel=me to a couple of links that were already on my site.

Micropub

Why would I want to authenticate? Well, there’s another piece of technology called micropub. Now, this is definitely more complicated than just adding rel=me to a few links. This is an end-point on my website and can be an end-point on your website and it accepts POST requests, that’s all it does. And if I’ve already got authentication taken care of and now I’ve got an end-point for POST requests, I’ve basically got an API, which means I can post to my website from other places. Once that end-point exists, I can use somebody else’s website to post to my website, as long as they’ve got this micropub support. I log in with that IndieAuth flow and then I’m using somebody else’s website to post to my website. That’s pretty nice. As long as these services have micropub support, I can post from somebody else’s posting interface to my own website and choose how I want to post.

In this example there, I was using a service called Quill; it’s got a nice interface. You can do long-form writing on it. It’s got a very Medium-like interface for long-form writing because a lot of people—when you talk about why are they on Medium—it’s because the writing experience is so nice, so it’s kind of been reproduced here. This was made by a friend of mine named Aaron Parecki and he makes some other services too. He makes OwnYourGram and OwnYourSwarm, and what they are is they’re kind of translation services between Instagram and Swarm to micropub.

Instagram and Swarm do not provide micropub support but by using these services, authenticating with these services using the rel=me links, I can then post from Instagram and from Swarm to my own website, which is pretty nice. If I post something on Swarm, it then shows up on my own website. And if I post something on Instagram, it goes up on my own website. Again I’m piggy-backing. There’s all this hard work of big teams of designers and engineers building these apps, Instagram and Swarm, and I’m taking all that hard work and I’m using it to post to my own websites. It feels kind of good.

Screenshots of posts on Swarm and Instagram, accompanied by screenshots of the same content on adactio.com.

Syndication

There’s an acronym for this approach, and it’s PESOS, which means you Publish Elsewhere and Syndicate to your Own Site. There’s an alternative to this approach and that’s POSSE, or you Publish on your Own Site and then you Syndicate Elsewhere, which I find preferable, but sometimes it’s not possible. For example, you can’t publish on your own site and syndicate it to Instagram; Instagram does not allow any way of posting to it except through the app. It has an API but it’s missing a very important method which is post a photograph. But you can syndicate to Medium and Flickr and Facebook and Twitter. That way, you benefit from the reach, so I’m publishing the original version on my own website and then I’m sending out copies to all these different services.

For example, I’ve got this section on my site called Notes which is for small little updates of say, oh, I don’t know, 280 characters and I’ve got the option to syndicate if I feel like it to say, Twitter or Flickr. When I post something on my own website—like this lovely picture of an amazingly good dog called Huxley—I can then choose to have that syndicated out to other places like Flickr or Facebook. The Facebook one’s kind of a cheat because I’m just using an “If This Then That” recipe to observe my site and post any time I post something. But I can syndicate to Twitter as well. The original URL is on my website and these are all copies that I’ve sent out into the world.

Webmention

OK, but what about…what about when people comment or like or retweet, fave, whatever it is they’re doing, the copy? They don’t come to my website to leave a comment or a fave or a like, they’re doing it on Twitter or Flickr. Well, I get those. I get those on my website too and that’s possible because of another building block called webmention. Webmention is another end-point that you can have on your site but it’s very, very simple: it just accepts pings. It’s basically a ping tracker. Anyone remember pingback? We used to have pingbacks on blogs; and it was quite complicated because it was XML-RPC and all this stuff. This is literally just a post that goes “ping”.

Let’s say you link to something on my website; I have no way of knowing that you’ve linked to me, I have no way of knowing that you’ve effectively commented on something I’ve posted, so you send me a ping using webmention and then I can go check and see, is there really a link to this article or this post or this note on this other website and if there is: great. It’s up to me now what I do with that information. Do I display it as a comment? Do I store it to the database? Whatever I want to do.

And you don’t even have to have your own webmention end-point. There’s webmentions as a service that you can subscribe to. Webmention.io is one of those; it’s literally like an answering service for pings. You can check in at the end of the day and say, “Any pings for me today?” Like a telephone answering service but for webmentions.

And then there’s this really wonderful service, a piece of open source software called Bridgy, which acts as a bridge. Places like Twitter and Flickr and Facebook, they do not send webmentions every time someone leaves a reply, but Bridgy—once you’ve authenticated with the rel=me values—Bridgy monitors your social media accounts and when somebody replies, it’ll take that and translate it into a webmention and send it to your webmention end-point. Now, any time somebody makes a response on one of the copies of your post, you get that on your own website, which is pretty neat.

It’s up to you what you do with those webmentions. I just display them in a fairly boring manner, the replies appear as comments and I just say how many shares there were, how many likes, but this is a mix of things coming from Twitter, from Flickr, from Facebook, from anywhere where I’ve posted copies. But you could make them look nicer too. Drew McLellan has got this kind of face-pile of the user accounts of the people who are responding out there on Twitter or on Flickr or on Facebook and he displays them in a nice way.

Drew, along with Rachel Andrew, is one of the people behind Perch CMS; a nice little CMS where a lot of this technology is already built in. It has support for webmention and all these kind of things, and there’s a lot of CMSs have done this where you don’t have to invent this stuff from scratch. If you like what you see and you think, “Oh, I want to have a webmention end-point, I want to have a micropub end-point”, chances are it already exists for the CMS you’re using. If you’re using something like WordPress or Perch or Jekyll or Kirby: a lot of these CMSs already have plug-ins available for you to use.

Building Blocks

Those are a few technologies that we can use to try and bridge that gap, to try and still get the control of owning your own content on your own website and still have the convenience of those third party services that we get to use their interfaces, that we get to have those conversations, the social effects that come with having a large network. Relatively simple building blocks: rel=me, micropub and webmention.

But they’re not the real building blocks of the indie web; they’re just technologies. Don’t get too caught up with the technologies. I think the real building blocks of the indie web can be found here in the principles of the indie web.

There’s a great page of design principles about why are we even doing this. There are principles like own your own data; focus on the user experience first; make tools for yourself and then see how you can scale them and share them with other people. But the most important design principle, I think, that’s on that list comes at the very end and it’s this: that we should 🎉 have fun (and the emoji is definitely part of the design principle).

Your website is your playground; it’s a place for you to experiment. You hear about some new technologies, you want to play with them? You might not get the chance at work but you can try out that CSS grid and the service worker or the latest JavaScript APIs you want to play with. Use your website as a playground to do that.

I also think we should remember the original motto of the World Wide Web, which was: let’s share what we know. And over the next few days, you’re going to hear a lot of amazing, inspiring ideas from amazing, inspiring people and I hope that you would be motivated to maybe share your thoughts. You could share what you know on Mark Zuckerberg’s website. You could share what you know on Ev Williams’s website. You could share what you know on Biz Stone and Jack Dorsey’s website. But I hope you’ll share what you know on your own website.

Thank you.

A group of smiling people, gathered together at an Indie Web Camp.

Wednesday, May 2nd, 2018

Tuesday, April 3rd, 2018