jlelse's Blog

Thoughts, stories and ideas

Adding ActivityStreams representations to Hugo

Published on in 👨‍💻 Dev
Updated on

I promised and people already asked, so here is the first part of the documentation about how I enabled ActivityPub support on my Hugo-based blog:

The first step to enable ActivityPub support, was to get Hugo to generate ActivityStreams representations for posts and the ActivityPub actor. I did this by adding a custom output format and published the code as a Hugo module on Codeberg. See the README file there to learn about how to use it.

Those ActivityPub representations are used, whenever an ActivityPub implementation tries to re-fetch the article (for example when you search for the article URL in Mastodon) and also when my custom ActivityPub middleware (post about that is coming soon…) detects a new article on my blog (using a JSON Feed) and then sends it to the followers.

After configuring the custom output format, there’s now a generated index.ajson file next to every index.html file of pages and the homepage. Because I use Caddy (version 1) as a webserver, serving the static files from disc, I needed to configure Caddy to serve the index.ajson file with the correct MIME-type and instead of the HTML file whenever a request contains application/activity+json or application/ld+json in the Accept header.

The correct MIME-type can be configured like this in the Caddyfile:

mime {
    .json application/json
    .ajson application/activity+json

To serve the .ajson file instead of the default .html file, I used the following rewrite rule:

rewrite {
    if {>Accept} has application/activity+json
    if {>Accept} has application/ld+json
    if_op or
    to {path}index.ajson {path}/index.ajson {path}


Jan-Lukas Else
You can also create an anonymous comment.