Reading List

The most recent articles from a list of feeds I subscribe to.

Webmention Analytics

I'm a fan of webmentions. I've written about how to use them before, and I'm quite happy with having them on my site.

However, it can get difficult to see what’s going on with them - especially if there’s a lot of “background noise”. Many sites just scrape content from well-known blogs and republish it for SEO juice. If that content includes a link to your site, it can lead to webmention spam.

Unlike on social media, you also don’t get notifications or reports about incoming webmentions. You’re just handed a bunch of raw data to use however you like. That’s part of the beauty of the Indieweb though: you can tailor it to whatever suits you best.

I recently started playing around with the data I get from webmention.io to see if it could be displayed in a more meaningful way. The result is a new side project I call:

✨✨✨ Webmention Analytics ✨✨✨
You can see it in action in this demo on my site.

barchart showing days of the month at the x-axis and different amounts of webmentions on the y-axis.
Breakdown of webmentions per day

I built this with Eleventy and Netlify, mainly because that’s my favorite tech stack to tinker with. But for analytics that don’t have to be real-time, static site generators are actually a really good fit.

Expensive computations like parsing and analyzing 8000+ data points like this can be run once a day through a periodic build hook. The reports it generates are then instantly available to the user, while still being up-to-date enough.

Features

Permalink to “Features”
  • group webmention data by month
  • overview of webmentions by type (like, reply, repost, mention, bookmark…) and day
  • show top source URLs sending webmentions to your site
  • show top target URLs on your site receiving webmentions
  • show top tweets generating webmentions through brid.gy
  • check incoming webmentions against a blocklist of known “content scrapers” and spam domains
  • automatic daily updates with cron job
table showing most common sources and targets for webmentions
Top sources and targets
Webmentions flagged as spam

Get your own instance!

Permalink to “Get your own instance!”

If you also use webmention.io to show webmentions on your site, you can fork the code on Github and make your own instance of webmention-analytics. Just follow the instructions in the README to get started.

Keep in mind that this is still a very early version of a weekend side project, so there's probably a few things to iron out. Cheers!

Making Persistent Build Folders in Netlify

Static Site Generators are all-or-nothing. Each time they build a new version of the site, they throw away everything that was created before and start from scratch.

That’s usually what you want to ensure everything is up-to-date. But there are special cases when keeping parts of the previous build around makes sense. For example, If you fetch lots of data from an external source during your build, it might make sense to cache that data and re-use it again in the future.

I recently found such a case when working on the Eleventy webmentions feature. For each build, a script queries the webmention.io API and fetches all the webmentions for the site. That can be a lot of data - and most of it stays the same, so fetching everything new again each time is sort of wasteful.

A Cache Folder

Permalink to “A Cache Folder”

A better solution is to store the fetched webmentions locally in a separate _cache folder as JSON and give them a lastFetched timestamp. On the next go, we can load the old data straight from there and only query the API for webmentions newer than that timestamp.

My webmentions code does exactly that - but it had a big problem: that only worked locally. Since Netlify (where my site is hosted) throws everything out the window each time, I couldn’t use the cache there.

Plugins to the Rescue

Permalink to “Plugins to the Rescue”

To edit anything related to the Netlify build process itself, you need a build plugin. There is a directory of plugins available for you to choose from, but you can also define your own plugins and deploy them alongside the rest of your code.

To define a custom plugin, make a new directory called plugins and within that, a new directory for your code:

_cache
_site
src
plugins
└── webmention-cache
    ├── index.js
    └── manifest.yml
package.json
netlify.toml

Your plugin should contain at least two files: a manifest with some metadata, and the actual plugin code.
For the manifest file, let’s just set a name:

# manifest.yml
name: webmention-cache

The meat of the plugin is in the index.js file. There are lots of things you could do here- but for this usecase, it’s enough to define an object with two functions. These are hooks that will be called on specific parts of the build process that Netlify runs.

Both functions will be given some arguments, and among them is the utils object we can use to access the internal build cache:

// index.js
module.exports = {
    // Before the build runs,
    // restore a directory we cached in a previous build.
    // Does not do anything if:
    //  - the directory already exists locally
    //  - the directory has never been cached
    async onPreBuild({ utils }) {
        await utils.cache.restore('./_cache')
    },
    // After the build is done,
    // cache directory for future builds.
    // Does not do anything if:
    //  - the directory does not exist
    async onPostBuild({ utils }) {
        await utils.cache.save('./_cache')
    }
}
  1. The onPreBuild hook looks for a previously cached _cache folder and restores it within the build.
  2. The onPostBuild hook takes the final build output, looks for changes in the _cache folder and saves it for later.

Because these hooks only look at changes that happen between the start and end of your build, your code needs to create the cache directory itself and write files to it as it runs. You can do that by using node’s filesystem functions, similiar to what I’ve done here.

It's important to note that this will not overwrite any existing files from your repository, so it only works when there is no _cache folder already committed to your site. It might make sense to add it to your .gitignore file.

Register the Plugin

Permalink to “Register the Plugin”

The last thing to do is to let the Netlify build script know you intend to use your plugin. You can register it with a line in your netlify.toml configuration file:

# netlify.toml
[[plugins]]
    package = "./plugins/webmention-cache"

Now, when you run a new build, you should see something like these lines in your deploy log:

2:02:08 PM: ❯ Loading plugins
2:02:08 PM:    - ./plugins/webmention-cache from netlify.toml
2:02:08 PM: ​
2:02:08 PM: ────────────────────────────────────────────────────────────────
2:02:08 PM:   1. onPreBuild command from ./plugins/webmention-cache         
2:02:08 PM: ────────────────────────────────────────────────────────────────
2:02:09 PM: ​
2:02:09 PM: (./plugins/webmention-cache onPreBuild completed in 302ms)
2:02:09 PM: ​
2:02:09 PM: ────────────────────────────────────────────────────────────────
2:02:09 PM:   2. build.command from netlify.toml                            
2:02:09 PM: ────────────────────────────────────────────────────────────────
2:02:09 PM: ​
2:02:09 PM: $ npm run build

...[lines omitted]...

2:02:12 PM: >>> 4240 webmentions loaded from cache
2:02:12 PM: >>> 6 new webmentions fetched from https://webmention.io/api
2:02:12 PM: >>> webmentions saved to _cache/webmentions.json

...[lines omitted]...

2:02:29 PM: ────────────────────────────────────────────────────────────────
2:02:29 PM:   3. onPostBuild command from ./plugins/webmention-cache        
2:02:29 PM: ────────────────────────────────────────────────────────────────
2:02:29 PM: ​
2:02:29 PM: (./plugins/webmention-cache onPostBuild completed in 53ms)

And that’s about it!

A year in review: 2020

I don't think I have to tell anyone why this year sucked, what with the pandemic and all. 2020 is going down in history as a massive crapstorm.

Still, I want to continue the tradition of “end-of-the-year” blogposts and since there’s already enough doom out there these days, I’m trying to focus on the good things that happened instead.

Work

Permalink to “Work”

The web industry is among the fortunate ones that are very well suited for remote and distributed work, which is why I was able to keep working from home throughout most of the year.

We rented a great new office in the spring that I’ve hardly been to since, but our team at Codista is quite used to working remote and we already had all the necessary infrastructure in place.

We had more than enough projects on our hands and we did some really interesting, challenging stuff that I can’t talk about (yet) 😉 - so all in all, work was good.

Writing

Permalink to “Writing”

I wrote nine posts in 2020 - which is fewer than last year, but all things considered, that’s ok. The most popular ones were:

Side Projects

Permalink to “Side Projects”

When the first lockdown hit, I kept occupied by building things - mostly in and around Eleventy, which helped me get ideas off the ground quickly. Here are some of these:

  • Eleventastic: my personal starter kit for Eleventy projects. I wanted to get rid of “external” build tools like Gulp and manage all pipelines inside Eleventy itself.

  • Eleventy Resumé: a simple microsite that functions as a CV/Resumé in web and print.

  • Whimsical Website Club: a collection of websites that spark joy by doing things a little bit less serious.

Speaking

Permalink to “Speaking”

I had some talks planned for 2020 which of course didn’t happen. I did a few online talks though and I participated in Inclusive Design 24, a free 24-hour livestream event where I talked about another side project, the “Emergency Website Kit”:

Events

Permalink to “Events”

The Webclerks team and I had the pleasure of hosting our own little virtual meetup event “Vienna Calling” on Twitch, and we had a phenomenal lineup. A big thank you again to all the speakers who joined us, as well as the rest of the team who made this happen behind the scenes.

BTW: You can find the full event as a playlist on Youtube:

Traveling

Permalink to “Traveling”

In the summer, the situation improved enough for me and my girlfriend to take some much needed vacation time. With international travel still closed, we decided to go on a road trip through Austria instead and it was awesome. This country has some really beautiful places in store.

A small cabin in the Austrian alps, under a clear blue sky
The Kanisalpe mountain range in Vorarlberg, Austria

We need the Web

Permalink to “We need the Web”

This year, more than ever, I realized the enormous impact the web has on all of us, and how important it is to keep it free and open. I know we’re all sick of doing things online all the time, but imagine for a moment what this year would have looked like had the web never been invented.

Millions of people would be completely isolated, even more would be out of their jobs. Schools could not operate. Civil rights movements would be almost impossible to organize. Global research projects like the development of a vaccine would take years longer. And you probably wouldn’t have seen the faces of your loved ones in months.

The web has become such an integral part of our lives that we sometimes take it for granted. It’s not. In fact this shitshow of a year should probably remind us that we need to take really good care of the things that are still connecting us.

Goals for 2021

Permalink to “Goals for 2021”

I’m not going to compare my goals from last year with what I’ve accomplished in 2020. I don’t think it matters. Give yourself a break this year - it’s OK if things didn’t turn out the way you wanted.

I’ll see you all in 2021. And hopefully we’ll all have a vaccine in our system and a better year ahead of us.

Other Year-in-Review Posts

Permalink to “Other Year-in-Review Posts”

Have you written one of these yourself? Let me know and get added here.

Whimsical Website Club

The web needs to take itself less seriously. It's barely out of its twenties and suddenly it's all like "I can't make fansites for hippos anymore, I have businesses to run".

It used to be cooler. It used to be weirder.

As Sarah Drasner puts it in “In Defense of a Fussy Website”:

While we’re all laser-focused on shipping the newest feature with the hottest software and the best Lighthouse scores, I’ve been missing a bit of the joy on the web. Apps are currently conveying little care for UX, guidance, richness, and — well, for humans trying to communicate through a computer, we’re certainly bending a lot to… the computer.

I really liked that post, so I made small website meant to showcase how a more personal web could look like, and hopefully give someone else inspiration to make their own corner of the web a bit weirder.

More whimsy, please!

Permalink to “More whimsy, please!”

Introducing: The Whimsical Web - a curated list of sites with an extra bit of fun.

I’ve collected a few of my favorites to start, but anyone can add a site to the list if it’s fun, quirky and personal.
Just open an issue on Github and let me know.

Let’s see some fussy websites!

The Return of the 90s Web

In big cultural concepts like music or fashion, things have a way of coming around full circle. I'm pretty sure someday grunge will come back as a hot new sample, and at some point our kids might think frosted hair tips are totally cool.

When I look at some of the trends on the web today, I wonder if we’re at that point yet. I wonder if we’re ready to revisit some of the ideas of the early web again.

Probably not in design - I’m afraid dancing-baby.gif is gone for good. But some of the broader ideas from back then are picking up a second wind lately, and I like it.

Serverside Rendering

Permalink to “Serverside Rendering”

After spending the better part of the last decade shifting rendering logic to the client, it looks like the pendulum is about to swing into the other direction again.

With projects like Phoenix Liveview or hey.com’s recent “it’s-just-HTML” approach, it seems like server-side rendering (SSR) is stepping back into the spotlight.

It makes sense - servers are really good at this, and sending compressed HTML through the network can be lightning fast. The classic request-response cycle has evolved as well: HTTP/2 and smart techniques like Turbolinks or just-in-time preloading allow for a much better experience now than when you first tried to load that Michael Jordan photo on the Space Jam website over dial-up.

Taking the responsibility of rendering UI and all the Javascript that comes with it off users’ shoulders would be a great old new strategy for the next generation of web apps.

No-Code Tools

Permalink to “No-Code Tools”

Frontpage and Dreamweaver were big in the 90s because of their “What You See Is What You Get” interface. People could set up a website without any coding skills, just by dragging boxes and typing text in them.

Of course they soon found that there was still source code underneath, you just didn’t see it. And most of the time, that source code was a big heap of auto-generated garbage - it ultimately failed to keep up with the requirements of the modern web.

the webflow interface, different design widgets and controls

Today our understanding of the web has improved, and so have our tools. Webflow is one of the contenders for the “no-code editor” trophy. The output it generates is far better.

These tools will probably not be a replacement for developers as a whole - complex projects still require tons of human brainpower to work. But for all the landing pages and marketing sites, this could be the holy grail of WYSIWYG we thought we had in the 90s.

Personal Websites

Permalink to “Personal Websites”

It might just be my IndieWeb filter bubble talking, but I think there is a renewed interest in personal websites. A lot of big social media giants are falling out of favor, and it becomes cool again to own a space on the web rather than being one of a billion usernames.

Our digital identities are becoming increasingly more important, and people become aware that they’re not in control of their data. Personal sites were very popular in the era before Myspace and Facebook, and it’s now easier than ever to build one.

Services like Carrd offer a straightforward way to create simple one-pagers, and their numbers show a lot of interest:

Blogging is gaining popularity again as well, used as a tool for self-marketing or simply to express opinions. There are lots of good options for people who want to pick up blogging - either on their own sites or with platforms like micro.blog, that offer more independence than Medium & Co.

Curated Feeds and Discovery

Permalink to “Curated Feeds and Discovery”

Another issue created by social media is the prevalence of “algorithmic feeds”. We decided that the constant stream of input for our eyeballs should never end, so we built these complex systems to generate new content for us based on our interests.

But these are giant black boxes, and nobody really knows what signals go into them. Throw advertising, “fake news” and a couple of trolls into the mix, and you get the mess we all know now.

That’s why many people crave a more controlled reading experience on their own terms. Chronological, personal, relevant - a bespoke magazine of trusted sources. A curated feed.

One way to achieve something like that is through plain ol’ boring RSS. One more thing that was said to be dead but is growing in popularity again:

Another possibility is to discover new content through human connections instead of algorithms. People we already know for their content recommend others in the same field, creating decentralized clusters of trusted information.

Website owners used to do this a lot in the days before search engines, by providing Blogroll Pages or forming Webrings with links to others in their cluster.

Webrings were a common way for people to connect their sites in the early web. To be a member of a webring, you had to embed a little widget on your site that contained a “forward”, a “backward”, and a “random” button. These buttons would then link to other sites in the ring.

BTW: If you want to host your own webring, I made this free Starter Kit for you.

Member of the An Example Webring webring

Previous Random Next

Smaller Communities and Web Monetization

Permalink to “Smaller Communities and Web Monetization”

Many independent creators are moving away from big “everyone’s on them” platforms back to private, more niche communities. New models for membership sites like Ghost’s “Members” feature enable creators to build communities on their content. People teach courses, self-publish books or provide APIs for specific topics.

Where the 90s had chatrooms and message boards, today there are tools like Discord or Twitch that help people with shared interests to connect with each other. These niche communities can then be a powerful userbase for independent businesses.

Of course the problem of monetization has existed from the very start of the web, and it’s still not easy today to earn money without splattering ads everywhere. But new standards like the Web Monetization API could be a very interesting solution, enabling creators to receive micro-payments for their content.

Learning from the Past

Permalink to “Learning from the Past”

I don’t know if all of these trends will really play out, or if we’re up for something completely different. I do think it’s a good idea to learn from the past though, because that is what keeps us moving forward.

So maybe the second 90s can be even better than the first. At least we’re done with NSYNC this time.