Skip to content

#blog

Website Refresh

Last time I wrote a blog post it was about rebuilding this website from Wordpress to hugo (opens in a new tab). That took six years of ruminating. And now, another six years (and one month) later, I rebuilt it again. Carlton danced the last one in; this time it’s a cup of tea, because that’s what six years of waiting for it all to blow over looks like.

That post also promised a retrospective on the Wordpress to Hugo migration “in the near future”. It has been six years. There is no retrospective. I’m choosing to believe this post counts.

Why

The honest answer is that the old setup had quietly rotted. The site was pinned to a version of Hugo from 2020. Every new item meant hand-writing a markdown file with a filename like aaron_paul-tv-breaking_bad-jesse_pinkman-0501-t_shirts-jesse_pinkmans_grenade_shirt.md and praying I got the underscores right, because the filename was the database. The “popular” and “trending” sections were held together with a shell script that scraped an undocumented analytics endpoint. It worked, but it was the kind of working where you don’t touch it in case it stops.

Possibly the biggest motivating factor, though, is that rebuilding a website in 2026 is a hell of a lot easier than it was at any point in the six years before this one (thanks, Anthropic (opens in a new tab)). In the interest of transparency: I did lean on Claude for this rebuild, but I had the luxury of writing a lot of the code by hand and hand-checking the code I didn’t write.

The setup wasn’t the only thing that rotted. The content did too. I’ve added four items since 2022. Four. I always wanted to post more, but every time I sat down to do it, the process of creating an item talked me out of it. My theory is that fixing the demotivating parts leads to fresher content. Let’s see.

What changed under the hood

The site is now built with Astro (opens in a new tab), TypeScript and Tailwind (opens in a new tab). It is still a pile of static HTML hosted on netlify (opens in a new tab), and the markdown files are still the database. Nothing runs on a server when you load a page. That was the one rule I refused to break.

Some specifics, for the few of you who care:

  • Every item is typed. The front matter is validated against a schema at build time. A missing field or a bad link breaks the build instead of rendering wrong.
  • Every URL survived. A migration reproduces Hugo’s slug rules exactly, checked against the live sitemap. Every old address exists or redirects. Your bookmarks should be safe.
  • Images are still generated at build time, same crops as before, now WebP and never upscaled. Astro caches the resized ones, so repeat builds finish in seconds.
  • Still (almost) no JavaScript. Search uses Pagefind (opens in a new tab), which downloads only the slivers of index your query needs. The only other script fills in an item’s name on the report page.
  • Builds happen on my machine and get pushed to netlify. Faster, and I’m no longer pinned to whatever a build image ships with. Not great for collaborators, of which I have zero.
  • Adding an item is a form now. A local-only tool fills in the front matter, checks the slug, resizes the screenshot and drops the file where it belongs. The underscores are nobody’s problem anymore.

What’s new for you

  • Items can have more than one place to buy them. The old site allowed exactly one link, which made no sense once the same shirt showed up on three stores.
  • Popular and trending are real now. Each item page counts its own views, in aggregate, per day, with no cookie and no tracking script. Trending is the last seven days, popular is all time. Give it a while to warm up.
  • Submitting an item doesn’t go through a Google form anymore. The submit page emails me a ready-to-drop file, so crowdsourced items get posted faster.
  • Reporting a broken link is one click. Every item has a “Something wrong? Report it” link. To keep the robots out of my inbox there’s a hidden field only a bot would fill in, a one-question quiz (the name of this website, and yes, people fail it) and a cap of twenty a day per person.
  • Dead links get caught before you find them. Theoretically. A script opens every store link in a real browser, including the Amazon pages that quietly turn into “currently unavailable”, and reports what died. Items with nowhere left to buy them say so. The “theoretically” is because a human still has to act on the report, and you’ve just read that human’s track record.

The design

The design hasn’t changed much, and that was on purpose. I spent a long time on it in 2020 and I still like it for its simplicity. Beyond some code cleanup and the move to tailwindcss (opens in a new tab), I kept it pretty much as it was. You may notice updated buttons and better accessibility, but otherwise it’s almost exactly how it was, which I think know is a good thing.

The boring but important bit

As before, this website uses some affiliate links, I don’t sell anything, and the imagery belongs to whoever made the films and shows. If you’ve spotted an item that should be on here, send it my way.

Enjoy the website.