New CSS, Who Dis? (2026 edition)
In the last couple of weeks, I've been making some changes to my website (with help from Claude Code) to make some improvements to my site's look + feel, as well as some accessibility improvements.
The last time I did a significant change on my site was in mid-2024, and I'd noted that:
In recent years I've been deprioritising my personal website (and the many IndieWeb-y things I want to do with it), both because I have far too many other projects as well as life stuff, and far too many hours in the day.
This also hasn't been helped by the fact that my site takes an age to build. Over the weekend I did a significant upgrade from an ~8 year old SSD to a new M.2 SSD, and my site still takes ~104 seconds to build. Hugo's known to be blazing fast, so if even that struggles with my site, I know I'm in trouble.
[...]
I've thought over the last couple of years that "I won't invest any time in my personal site, as I'll rebuild it soon", as I've wanted to migrate from a static site to a dynamic site. But that's never made it up the very long TODO list, so I thought that I should make some minor tweaks over the weekend, which are live as of this post landing.
I'm, unfortunately, a long way from being able to prioritise doing a rebuild of my website - and if I'm honest, I'm not sure I will be doing it even if I had the time.
I'm finding that actually I much prefer writing Markdown in my Neovim, instead of in one of the various Micropub editors I could be using, and having the ability to run my site with all my content locally is a nicer experience.
Also, I don't particularly want something dynamic, which is then vulnerable to gestures wildly at the state of CVEs right now.
With that in mind, I'm going to be sticking with my Hugo site for some time, so needed to make some much-needed improvements to both the user-facing site, as well as making it easier for me to maintain.
Putting the Social Media in the IndieWeb#
One of the things I've loved about having an IndieWeb site is that my website has become my source for my presence on social media.
I've been publishing IndieWeb-style posts on this site since ~2019, and it's been the primary way I've interacted with Twitter (until it became a Nazi bar), the Fediverse, Bluesky and even platforms like Meetup.com.
As part of this, I've decided to go "all in" on that as my design language, and for a lot of my feeds, you'll now see them represented as if you'd see them on social media - with "link previews", and rendering what interactions a post has had:

I quite like this rendering, and it makes it feel much more like my site is to me - it's my social media.
If you want to see it fully in action, check out the /all feed, which includes all of my content types, so you'll get a feel for the various types of content I post and how they present.
Better font size + page width#
Although I personally prefer reading a slightly wider page of content this may not be the most accessible choice, so I've trimmed the width of the content on the page.
Given the written prose is often the most important part of my website, it should be a little bit more "front and centre", and so I've increased the font size for the key parts of my site - it's something I've been meaning to do for some time, but never got around to.
As an example, we can look at the previous iteration of this site, circa my last post in 2024:

Now, that same post renders like:

(Note that there's a slight difference between the posts in styling due to the top screenshot being taken where the :visited selector fires, as I've previously visited a number of those pages)
Better contrast#
I know that I've had feedback from folks about the colours on the site and whether they're accessible / readable - I've recently made some steps to make it a bit more clear, but appreciate any suggested improvements!
Doing more with my step counts#
I've been tracking my step counts for just over 7 years now, and they've been a boring "I walked ... steps".
With this site update, I've now got a year-by-year breakdown of my steps over time, a per-month breakdown or over a given year.
(Because a step count is posted the day after the steps are stepped, there are some cases where a previous year/month's steps appear - I'll fix that at some point!)
Removing "post frequency"#
I'd previously had a /post-frequency page, which would show how often I post specific types of content, but I've removed it as part of the most recent changes.
This page wasn't great because:
- the colours + text wasn't very readable
- the content types I post generally have different behaviours, and it's more useful to show Articles with their own view of the data vs IndieWeb-style pieces of content
- I would now prefer to use a different tool to visualise this, like Evidence
- it also wasn't the most performant, requiring a rebuild of a large JSON file on each tweak to content
You can see a previous version on the Wayback Machine, to get a feel for why it wasn't great.
4 years of Hugo upgrades#
As someone who's on record as liking to keep their software updated, it's a little embarrassing to say that I've not been updating Hugo for over 4 years π
Each time recently I'd looked at the upgrade, I'd ended up hitting a few breaking changes that couldn't be feasibly handled without some more in-depth migrations.
For instance, I've been using the kind parameter in my posts to indicate i.e. "this is a blog post" or "this is a repost". When Hugo v0.144.0 (2025-02-17) deprecated it, and future changes removed it as a parameter to use, this meant that I needed to migrate all of my content to use a new hierarchy of parameters.
To do this, I needed to change ~45k historically created files, which wasn't too bad. The real issue was that I'd need to do this for any new content to the site.
When I publish IndieWeb-style posts to my site, I end up using my Micropub server, which was previously a Java web API.
I haven't really touched Java for ~4 years, and so the cost of maintaining the codebase was ramping up, as well as that being a project I'd built under the guise of "I want to write more code", and so there was at times a bit too much code + test infrastructure to making straightforward changes.
For a few years, I've been wanting to rewrite my Micropub endpoint in Go - a language I use much more - but the cost of doing that was quite high given the amount of things I had to do at any given time.
This blocker meant that I wouldn't be able to proceed with doing much on my site, so I ended up stagnating a little.
Given the Micropub rewrite was a daunting task that made it hard for me to start, I leant on AI to speed me up, doing some iterative work to extract out the key features I needed / didn't want porting, doing the work with some guidance, and ending up with the resulting endpoint being in a state where I can make changes more quickly, which is nice.
Once that was done, I could then start the process of working through the upgrade process of Hugo - with thanks to Claude Code chugging along in the background - and making sure that breaking changes in Hugo were handled by my site + Micropub endpoint in lockstep.
This allowed me to upgrade from Hugo v0.101.0 (2022-06-16) to Hugo v0.168.0 (2026-10-13) π
Faster builds#
Alongside the Hugo upgrades, I also made a few other big changes along the way:
- disabled
enableGitInfo- this was another big change I needed my Micropub endpoint to be rewritten in Go, so I could handle setting
lastmodon updates
- this was another big change I needed my Micropub endpoint to be rewritten in Go, so I could handle setting
- removed a number of unnecessary pages being updated
- moved to date-based pagination
- instead of a new post leading to a lot of knock-on updates in paginated feeds, this then means we only update the given day's feed
- increased the size of the CI runners I use
- removing a separate build + deploy stage, moving it into a single deploy
- removed a reference to "this site was built by commit ..." on every page
- reducing the size of the sitemap and other generated files
- simplifying my tags pages, i.e. /tags/www.jvt.me is now a single page, instead of paginating
Before these changes, I was seeing up to ~9m of total time from commit to it being live. If we look at this commit, which adds context for the post being created, we can see that:
buildjob:- ~2m was cloning the Git repo (with full history, just shy of 100k commits)
- ~4m was building the site (see below)
- ~20s was uploading the built site as an Artifact, to then be used by the
deployjob
deployjob:- ~9s was doing a shallow cloning of the Git repo
- ~70s was performing the deployment
- The deploy needed to change many files:
Identified 2660 file(s) to upload, totaling 223 MB, and 0 file(s) to delete.
Previous Hugo site build breakdown
$ hugo --verbose --minify --buildFuture
hugo: collected modules in 1705 ms
Start building sites β¦
hugo v0.101.0-466fa43c16709b4483689930a4f9ac8add5c9f66+extended linux/amd64 BuildDate=2022-06-16T07:09:16Z VendorInfo=hugoguru
INFO 2026/10/21 22:15:23 syncing static files to /
| EN
-------------------+--------
Pages | 94130
Paginator pages | 3153
Non-page files | 0
Static files | 80
Processed images | 0
Aliases | 2716
Sitemaps | 1
Cleaned | 0
Total in 226167 msAfter all my changes, I'm seeing ~2m of total time from commit to it being live, where we see:
- ~10s doing a shallow clone of the repo
- ~60s was building the site (see below)
- ~15s of deploying the site
- The deploy needed to change very few files:
Identified 12 file(s) to upload, totaling 877 kB, and 0 file(s) to delete.
- The deploy needed to change very few files:
Current Hugo site build breakdown
$ hugo --minify --buildFuture
hugo: collected modules in 1887 ms
Start building sites β¦
hugo v0.168.0+extended+withdeploy linux/amd64 BuildDate=unknown VendorInfo=docker
β EN
βββββββββββββββββββΌβββββββ
Pages β 70587
Paginator pages β 19
Non-page files β 0
Static files β 96
Processed images β 0
Aliases β 1680
Cleaned β 0
Total in 58976 msThis is a pretty great saving! I'm no longer wasting a lot of bandwidth, and my site's build is pretty great for local development and when pushing content changes out.
Standard.site metadata#
I've recently also added support for the standard.site lexicon, with thanks to Bridgy Fed, but:
- it doesn't appear to suggest my site as a "publication" when sharing links to my site
- it requires me (for now) manually update my posts' metadata, once they've been syndicated to the Atmosphere, with a link to the
at://metadata for a given post
You can see it in action in Thirteen backlogs in a trenchcoat: Analysing Renovate's many requests.
Popular posts#
I've had a /popular-posts page for some time, but it was a bit awkward to add new posts to.
It's now improved in how it displays, and comes with an RSS feed, too!
Infrastructure improvements#
Better CloudFront caching#
I've made some changes to how my CloudFront responses get cached, reducing ~2GB/day worth of traffic being served - nice!
Migrating from Lambda@Edge to CloudFront Functions#
A small bit of work, but getting these migrated over should simplify the management, and hopefully be cheaper, too.
Migrating media.jvt.me to Amazon S3 + CloudFront#
Something that's been on my TODO list for a while is migrating my media.jvt.me domain from Netlify to Amazon S3 + CloudFront.
There's a few reasons, but one of the big ones has been recent changes Netlify have done to make their billing pretty painful by introducing "credits".
By making it so every time I want to upload an image, I was spending 15 of my 300 credits each time that push happened, which, on top of some of the bandwidth I use on my sites, was pushing me over limits each month.
I don't fault Netlify for looking at additional monetisation, and have been a happy user (and small-ish customer) - but it was enough to make me move some of my sites away from it to simplify the billing for my personal websites. I'd also moved my personal website's build to S3+CloudFront in 2021 due to the hosted build environment being very expensive.
I'll still keep some stuff on Netlify where I'm getting paid to host things, so they're still receiving some of my money, but I prefer AWS' billing to Netlify's new complex billing - let that settle in!
With me rewriting my Micropub endpoint, I could then look at migrating over to S3-backed media storage.
Using AI to speed me up#
While I'm doing more with AI in my job (as a lot of us are) I've also found that I've ended up leaning on it for a few of my personal projects, especially to help unblock me in some cases where I'm feeling the mountain of my TODO list.
I love my website, and in the past it's brought me a lot of joy to work on. But in recent years, it's become a slog and a burden.
As I don't have any other team members to delegate tasks to, I've found that using my Claude for Open Source subscription, and historically my GitHub Copilot access, have been useful to get there.
For all these changes, I've been deciding what I want to do, and iterating over the design choices, but I haven't necessarily wanted to fight with the Hugo templates or the CSS tweaks to make it "just right".
But now I've done some recent changes to my site, it's made it a lot nicer to be able to start making other changes, and more generally get back to enjoying working on my site, which is nice.
To be very explicit for folks who may read this and worry - a reminder that I'm still very strongly pro human written words, and that this blog will not become slop. I'll continue to write my own words and being explicit about how much AI is used in my content, and put out things into the world that are my own thinking and words.
