Tags: indie



Tuesday, October 17th, 2017

@20 (Ftrain.com)

Paul Ford marks two decades of publishing on his own site.

Some days I want to erase this whole thing—much of the writing is sloppy and immature, and I was, too. But why bother to hit the red button? The path of the Internet has seen fit to do that for me.

The Era of Newshammer - daverupert.com

Dave has redesigned his site. Now it’s extra Dave-y.

Tuesday, October 3rd, 2017

Getting the blog back together

Simon has revived his blog …and he’s importing his writings from not-his-blog too.

Monday, September 25th, 2017

The Decentralized Social Web

Excellent presentation slides on all things Indie Web.

Tuesday, September 12th, 2017

V6: The Archive | Rob Weychert

Rob has redesigned his site and it’s looking lovely. Here’s the first part of a three-part series on the rationale behind the relaunch:

I don’t pretend everything I do or say online is worthy of preservation. But while I’m still breathing, I want to be the one who decides what gets preserved and what doesn’t. And I want it all to be available in one place. Owning and operating my own site is the only way.

Hell, yeah!

Friday, September 1st, 2017

A New bradfrost.com! | Brad Frost

I’m doubling down on owning my own content, so I’m excited to have a less-crusty home for it all.

It’s fun! In a world where even sites that aren’t Medium dot com are looking like Medium dot com, I’m excited to try something different.

Wednesday, August 23rd, 2017

Decentralize It!

Paul Ford jots down his thoughts on that report on Ev’s blog:

The web is inherently decentralized, which has made it much easier for large companies to create large, centralized platforms. It’s a paradox and very thorny. I’m writing this on a centralized platform called Medium. Clap!

I like his geeky idea for mini self-contained social networks:

What I want is like, 5 of these little computers and whenever I see a truly trusted friend, I just give them one. And they take it home, and plug it in somewhere, and now we’re on the same, secure network together. Sharing files and with a little messageboard. Maybe after 5 computers the network can’t get any bigger. And if you unplug one your whole archive goes down. I don’t know. I’m riffing here.

The Decentralized Web

A report by the Digital Currency Initiative and the Center for Civic Media. Download the PDF or read the executive summary.

In this report, we explore two important ways structurally decentralized systems could help address the risks of mega-platform consolidation: First, these systems can help users directly publish and discover content directly, without intermediaries, and thus without censorship. All of the systems we evaluate advertise censorship-resistance as a major benefit. Second, these systems could indirectly enable greater competition and user choice, by lowering the barrier to entry for new platforms. As it stands, it is difficult for users to switch between platforms (they must recreate all their data when moving to a new service) and most mega-platforms do not interoperate, so switching means leaving behind your social network.

Tuesday, August 22nd, 2017

A few technical words about Upsideclown, and some thoughts about audiences and the web (17 Aug., 2017, at Interconnected)

Matt writes about the pleasure of independent publishing on the web today:

It feels transgressive to have a website in 2017. Something about having a domain name and about coding HTML which is against the grain now. It’s something big companies do, not small groups. We’re supposed to put our content on Facebook or Medium, or keep our publishing to an email newsletter. But a website?

But he points out a tension between the longevity that you get from hosting the canonical content yourself, and the lack of unified analytics when you syndicate that content elsewhere.

There’s no simple online tool that lets me add up how many people have read a particular story on Upsideclown via the website, the RSS feed, and the email newsletter. Why not? If I add syndication to Facebook, Google, and Apple, I’m even more at sea.

Saturday, August 12th, 2017

I made a style guide for my personal web site and you should too.—zachleat.com

Here’s Zach’s style guide. But the real reason I’m linking to this is his lovely description of having a personal website that grows over time:

As my own little corner of the web unceremoniously turned ten years old this year, it’s really starting to feel more like a garden than a piece of software. I certainly enjoy tending to it. I can plant what I like and with proper care it can grow into something useful.

Wednesday, July 26th, 2017

Posting to my site

I was idly thinking about the different ways I can post to adactio.com. I decided to count the ways.

Admin interface

This is the classic CMS approach. In my case the CMS is a crufty hand-rolled affair using PHP and MySQL that I wrote years ago. I log in to an admin interface and fill in a form, putting the text of my posts into a textarea. In truth, I usually write in a desktop text editor first, and then paste that into the textarea. That’s what I’m doing now—copying and pasting Markdown from the Typed app.

Directly from my site

If I’m logged in, I get a stripped down posting interface in the notes section of my site.

Notes posting interface


This is how I post links. When I’m at a URL I want to bookmark, I hit the “Bookmark it” bookmarklet in my browser’s bookmarks bar. That pops open a version of the admin interface tailored specifically for links. I really, really like bookmarklets. The one big downside is that they don’t work on mobile.

Text message

This is something I knocked together at Indie Web Camp Brighton 2015 using the Twilio API. It’s handy for posting notes if I’m travelling somewhere and data is at a premium. But I don’t use it that often.


Thanks to Aaron’s OwnYourGram service—and the fact that my site has a micropub endpoint—I can post images from Instagram to my site. This used to happen instantaneously but Instagram changed their API rules for the worse. Between that and their shitty “algorithmic” timeline, I find myself using the service less and less. At this point I’m only on their for the doggos.


Like OwnYourGram, Aaron’s OwnYourSwarm allows me to post check-ins and photos from the Swarm app to my site. Again, micropub makes it all possible.

OwnYourGram and OwnYourSwarm are very similar and could probably be abstracted into a generic service for posting from third-party apps to micropub endpoints. I’d quite like to post my check-ins on Untappd to my site.

Other people’s admin interfaces

Thanks to rel="me" and IndieAuth, I can log into other people’s posting interfaces using my own website as the log-in, and post to my micropub endpoint, like this. Quill is a good example of this. I don’t use it that much, but I really should—the editor interface is quite Medium-like in its design.

Anyway, those are the different ways I can update my website that I can think of right now.


In terms of output, I’ve got a few different ways of syndicating what I post here:

Just so you know, if you comment on one of my posts on Facebook, I probably won’t see it. But if you reply to a copy of one of posts on Twitter or Instagram, it will show up over here on adactio.com thanks to the magic of Brid.gy and webmention.

Tuesday, July 18th, 2017

Reflections on Two Years of Indieweb

Alex Kearney looks back on two years of owning her own data.

With a fully functional site up and running, I focused on my own needs and developed features to support how I wanted to use my site. In hind-sight, that’s probably the most indie thing I could’ve done, and how I should’ve started my indieweb adventure.

This really resonates with me.

One of the motivating features for joining the indieweb was the ability to keep and curate the content I create over time.

Terrific post!

Here’s to two more years.

Monday, July 17th, 2017

Implementing Webmentions

Drew has been adding webmention support not just to his own site, but any site using Perch. This account of his process is a really good overview of webmentions.

Tuesday, July 11th, 2017

IndieWeb is on Open Collective

You can help support the indie web community with their fairly modest costs: about $200 each month for hosting, domain names, and the like. Also:

We want IndieWeb events to be as accessible as possible, regardless of personal barriers. Because of this, we have offered a travel scholarship fund in the past to underrepresented groups thanks to our generous sponsors. Your support will allow us to continue to offer and expand this scholarship fund, helping make sure that IndieWebCamps represent everyone.

Sunday, June 18th, 2017

IndieWebifying my website: part 1, the why & how – AltPlatform

Richard MacManus begins to document the process of making his website part of the indie web.

Wednesday, June 14th, 2017

The IndieWeb Movement Will Help People Control Their Own Web Presence?

A pretty good summary of some key indie web ideas.

Sunday, June 4th, 2017

Month maps

One of the topics I enjoy discussing at Indie Web Camps is how we can use design to display activity over time on personal websites. That’s how I ended up with sparklines on my site—it was the a direct result of a discussion at Indie Web Camp Nuremberg a year ago:

During the discussion at Indie Web Camp, we started looking at how silos design their profile pages to see what we could learn from them. Looking at my Twitter profile, my Instagram profile, my Untappd profile, or just about any other profile, it’s a mixture of bio and stream, with the addition of stats showing activity on the site—signs of life.

Perhaps the most interesting visual example of my activity over time is on my Github profile. Halfway down the page there’s a calendar heatmap that uses colour to indicate the amount of activity. What I find interesting is that it’s using two axes of time over a year: days of the month across the X axis and days of the week down the Y axis.

I wanted to try something similar, but showing activity by time of day down the Y axis. A month of activity feels like the right range to display, so I set about adding a calendar heatmap to monthly archives. I already had the data I needed—timestamps of posts. That’s what I was already using to display sparklines. I wrote some code to loop over those timestamps and organise them by day and by hour. Then I spit out a table with days for the columns and clumps of hours for the rows.

Calendar heatmap on Dribbble

I’m using colour (well, different shades of grey) to indicate the relative amounts of activity, but I decided to use size as well. So it’s also a bubble chart.

It doesn’t work very elegantly on small screens: the table is clipped horizontally and can be swiped left and right. Ideally the visualisation itself would change to accommodate smaller screens.

Still, I kind of like the end result. Here’s last month’s activity on my site. Here’s the same time period ten years ago. I’ve also added month heatmaps to the monthly archives for my journal, links, and notes. They’re kind of like an expanded view of the sparklines that are shown with each month.

From one year ago, here’s the daily distribution of

And then here’s the the daily distribution of everything in that month all together.

I realise that the data being displayed is probably only of interest to me, but then, that’s one of the perks of having your own website—you can do whatever you feel like.

Tuesday, May 30th, 2017

Micropub is a W3C Recommendation • Aaron Parecki

I was just talking about micropub …and now it’s officially a W3C spec. Great work!

If you’re building a blogging platform, you can allow your users choose from a wide variety of posting clients by implementing the Micropub spec.

If you’re building a posting client and want it to work with many different server backends instead of hard-coding it to Twitter or other proprietary APIs, implement the Micropub spec and you’ll quickly have people eager to start using the app!

Checking in at Indie Web Camp Nuremberg

Once I finished my workshop on evaluating technology I stayed in Nuremberg for that weekend’s Indie Web Camp.

IndieWebCamp Nuremberg

Just as with Indie Web Camp Düsseldorf the weekend before, it was a fun two days—one day of discussions, followed by one day of making.

IndieWebCamp Nuremberg IndieWebCamp Nuremberg IndieWebCamp Nuremberg IndieWebCamp Nuremberg

I spent most of the second day playing around with a new service that Aaron created called OwnYourSwarm. It’s very similar to his other service, OwnYourGram. Whereas OwnYourGram is all about posting pictures from Instagram to your own site, OwnYourSwarm is all about posting Swarm check-ins to your own site.

Usually I prefer to publish on my own site and then push copies out to other services like Twitter, Flickr, etc. (POSSE—Publish on Own Site, Syndicate Elsewhere). In the case of Instagram, that’s impossible because of their ludicrously restrictive API, so I have go the other way around (PESOS—Publish Elsewhere, Syndicate to Own Site). When it comes to check-ins, I could do it from my own site, but I’d have to create my own databases of places to check into. I don’t fancy that much (yet) so I’m using OwnYourSwarm to PESOS check-ins.

The great thing about OwnYourSwarm is that I didn’t have to do anything. I already had the building blocks in place.

First of all, I needed some way to authenticate as my website. IndieAuth takes care of all that. All I needed was rel="me" attributes pointing from my website to my profiles on Twitter, Flickr, Github, or any other services that provide OAuth. Then I can piggyback on their authentication flow (this is also how you sign in to the Indie Web wiki).

The other step is more involved. My site needs to provide an API endpoint so that services like OwnYourGram and OwnYourSwarm can post to it. That’s where micropub comes in. You can see the code for my minimal micropub endpoint if you like. If you want to test your own micropub endpoint, check out micropub.rocks—the companion to webmention.rocks.

Anyway, I already had IndieAuth and micropub set up on my site, so all I had to do was log in to OwnYourSwarm and I immediately started to get check-ins posted to my own site. They show up the same as any other note, so I decided to spend my time at Indie Web Camp Nuremberg making them look a bit different. I used Mapbox’s static map API to show an image of the location of the check-in. What’s really nice is that if I post a photo on Swarm, that gets posted to my own site too. I had fun playing around with the display of photo+map on my home page stream. I’ve made a page for keeping track of check-ins too.

All in all, a fun way to spend Indie Web Camp Nuremberg. But when it came time to demo, the one that really impressed me was Amber’s. She worked flat out on her site, getting to the second level on IndieWebify.me …including sending a webmention to my site!

IndieWebCamp Nuremberg

Tuesday, May 23rd, 2017

Going offline at Indie Web Camp Düsseldorf

I’ve just come back from a ten-day trip to Germany. The trip kicked off with Indie Web Camp Düsseldorf over the course of a weekend.

IndieWebCamp Düsseldorf 2017

Once again the wonderful people at Sipgate hosted us in their beautiful building, and once again myself and Aaron helped facilitate the two days.

IndieWebCamp Düsseldorf 2017

Saturday was the BarCamp-like discussion day. Plenty of interesting topics were covered. I led a session on service workers, and that’s also what I decided to work on for the second day—that’s when the talking is done and we get down to making.

IndieWebCamp Düsseldorf 2017 IndieWebCamp Düsseldorf 2017 IndieWebCamp Düsseldorf 2017 IndieWebCamp Düsseldorf 2017

I like what Ethan is doing on his offline page. He shows a list of pages that have been cached, but instead of just listing URLs, he shows a title and description for each page.

I’ve already got a separate cache for pages that gets added to as the user browses around my site. I needed to figure out a way to store the metadata for those pages so that I could then display it on the offline page. I came up with a workable solution, and interestingly, it involved no changes to the service worker script at all.

When you visit any blog post, I put metadata about the page into localStorage (after first checking that there’s an active service worker):

if (navigator.serviceWorker && navigator.serviceWorker.controller) {
  window.addEventListener('load', function() {
    var data = {
      "title": "A minority report on artificial intelligence",
      "description": "Revisiting Spielberg’s films after a decade and a half.",
      "published": "May 7th, 2017",
      "timestamp": "1494171049"

In my case, I’m outputting the metadata from the server, but you could just as easily grab some from the DOM like this:

var data = {
  "title": document.querySelector("title").innerText,
  "description": document.querySelector("meta[name='description']").getAttribute("contents")

Meanwhile in my service worker, when you visit that same page, it gets added to a cache called “pages”. Both localStorage and the cache API are using URLs as keys. I take advantage of that on my offline page.

The nice thing about writing JavaScript on my offline page is that I know the page will only be seen by modern browsers that support service workers, so I can use all sorts of fancy from ES6, or whatever we’re calling it now.

I start by looping through the keys of the “pages” cache (that’s right—the cache API isn’t just for service workers; you can access it from any script). Then I check to see if there is a corresponding localStorage key with the same string (a URL). If there is, I pull the metadata out of local storage and add it to an array called browsingHistory:

const browsingHistory = [];
.then( cache => {
  .then(keys => {
    keys.forEach( request => {
      let data = JSON.parse(localStorage.getItem(request.url));
        if (data) {
          data['url'] = request.url;

Then I sort the list of pages in reverse chronological order:

browsingHistory.sort( (a,b) => {
  return b.timestamp - a.timestamp;

Now I loop through each page in the browsing history list and construct a link to each URL, complete with title and description:

let markup = '';
browsingHistory.forEach( data => {
  markup += `
<h2><a href="${ data.url }">${ data.title }</a></h2>
<p>${ data.description }</p>
<p class="meta">${ data.published }</p>

Finally I dump the constructed markup into a waiting div in the page with an ID of “history”:

let container = document.getElementById('history');
container.insertAdjacentHTML('beforeend', markup);

All those steps need to be wrapped inside the then clause attached to caches.open("pages") because the cache API is asynchronous.

There you have it. Now if you’re browsing adactio.com and your network connection drops (or my server goes offline), you can choose from a list of pages you’ve previously visited.

The current situation isn’t ideal though. I’ve got a clean-up operation in my service worker to limit the number of items stored in my “pages” cache. The cache never gets bigger than 35 items. But there’s no corresponding clean-up of metadata stored in localStorage. So there could be a lot more bits of metadata in local storage than there are pages in the cache. It’s not harmful, but it’s a bit wasteful.

I can’t do a clean-up of localStorage from my service worker because service workers can’t access localStorage. There’s a very good reason for that: the localStorage API is synchronous, and everything that happens in a service worker needs to be asynchronous.

Service workers can access indexedDB: it’s asynchronous. I could use indexedDB instead of localStorage, but I’m not a masochist. My best bet would be to use the localForage library, which wraps indexedDB in the simple syntax of localStorage.

Maybe I’ll do that at the next Homebrew Website Club here in Brighton.