blog

The software that produces this blog · visit blog

  • v4.3 - Project info and link syntax

    Added a project info system for devlog entries. Each devlog tag can now have associated metadata defined in src/data/projects.ts including a description, source repo, live URL, and additional links. A new ProjectInfo component displays this information on devlog pages, replacing the hardcoded spacetraders links that were there before.

    Extended the remark-post-links plugin to support a link: prefix for external markdown links. This allows posts to reference external URLs with a shorthand syntax like [text](link:slug) where the slug maps to a predefined URL.

    Also added post filtering to the blog index and backfilled many devlog entries for the spacetraders-v1 and bags projects.

  • v4.2 - Blog post series navigation

    Added a :::series remark plugin that allows blog posts to declare they belong to a series. When a post includes :::series[series-name], the plugin generates navigation showing all posts in the series with links to the others and “(this post)” for the current one.

    Series are defined in src/data/series.ts with a title, ordered list of post slugs, and an optional footer HTML file for common content. Updated the “Steering the Vibe” posts to use this new directive instead of manually including the info box in each post.

  • v4.1 - Link syntax with validation

    Added a custom remark plugin that introduces a post: link syntax for referencing other posts. Instead of writing full URLs like /blog/2025/12/07/steering-the-vibe-commits/, I can now write [link text](post:steering-the-vibe-commits) and the plugin resolves it to the correct URL based on the post’s date. It also supports anchor links like post:slug#section.

    The plugin validates links at build time and throws a helpful error if a referenced post doesn’t exist, listing some available slugs to help track down typos. Went through all existing posts to convert hardcoded internal links to the new syntax.

    Also added a VS Code launch configuration for the dev server.

  • v4.0 - Astro migration complete

    Finished the Astro migration by removing Jekyll entirely from the project.

    Moved all assets from the root assets/ directory to public/assets/ where Astro expects static files. Fixed several styling issues that were lingering from the conversion: inline code now has proper styling, the clearfix for floated images in posts works correctly, and the devlog aggregate page layout was cleaned up. Also improved the devlog toggle button styling.

    Did some general cleanup - extracted a helper function for devlog URLs, removed unused layout frontmatter fields, and dropped netlify-cli from the dependencies because it breaks github runners (i’ll call it via npx). Regenerated the package-lock file to clean up dependency changes.

  • v4.0.0-alpha.3 - Jekyll migration features

    Built a remark plugin to handle Jekyll include tags during the Astro migration. Started in JavaScript then converted it to TypeScript for better type safety. The plugin transforms Jekyll-style includes into their Astro equivalents during markdown processing.

    Replaced all the Jekyll post_url liquid tags with actual URLs across a dozen posts. This was necessary since Astro doesn’t have an equivalent to Jekyll’s post linking system.

    Added several missing pages to reach feature parity with the old site: card-game, bubble-bobble, bookmarklet builder, and a proper categories page for the blog. Also created tag-based RSS feeds for the devlog so each project can have its own feed.

    Implemented Open Graph card support across all the main pages for better social media previews. Various content fixes for code blocks and formatting issues that came through from the Jekyll conversion.

  • v4.0.0-alpha.2 - Astro polish

    Polished up the Astro migration with a bunch of fixes and new features.

    Added RSS feeds for both the blog and devlog sections. Created several new pages that were missing from the migration: the bookmarklet builder, bubble bobble, slippery boxes, spacetraders, talks, and privacy policy pages.

    Fixed up the share buttons component and improved the link card styling. Updated the layout to handle social images better. Various content fixes across devlogs, links, notes, and posts - mostly correcting formatting issues that came through from the Jekyll conversion.

    Expanded the migration verification script to catch more edge cases and added a verify ignore list for known acceptable differences.

  • v4.0.0-alpha.1 - Astro conversion

    I migrated my blog from Jekyll to Astro. This has been a long time coming - Jekyll served me well for years but I’ve increasingly found myself fighting against it rather than working with it.

    The migration involved converting all my HTML blog posts to markdown, setting up the Astro content collections for devlogs and links, and rebuilding the pages (apps, links, 404, etc). I also created a migration verification script to ensure nothing was lost in translation.

    The existing devlog entries from the Jekyll version were migrated across as part of this work. The new Astro setup uses a cleaner content structure and should make future updates much easier to manage.

  • v3.3 - Jekyll 4 Upgrade

    Upgraded the Jekyll part of the site from version 3 to 4. This involved adding a proper Gemfile with version pinning, refactoring the SCSS structure to extract variables into a dedicated partial, and updating some template syntax. The build script and Docker setup needed adjustments to work with the new version.

    While working on a post I added a new info callout component for highlighted asides. Also set up redirects for the old asteroid-logistics game URLs and improved the CI workflow by caching Ruby gems.

  • v3.2 - og:image for notes

    A while back I added og:image generation for posts and pages and later extended it to support devlogs. I did not however add it to notes for two reasons:

    • My github action that deploys the blog generates all the images on every push - adding notes would more than double deploy time
    • I didn’t want to solve the above issue by commiting the images to source

    Today I solved this via two key changes:

    1. The generator will now skip existing images by default and;
    2. The generated images are cached via actions/cache.

    The relative section from the github workflow looks like this:

    yaml
    - uses: actions/cache@v4 name: Restore cached images with: path: _site/assets/cards key: cards-${{ github.sha }} restore-keys: | cards- - run: ./scripts/generate-images.sh ${GITHUB_WORKSPACE} name: Generate images

    The restore key matching on cards- means the last run always matches, returning all previously generated images. The result is now each notes page has a unique og:image:

    notes on ravendb image

  • v3.1 - square og:image

    I implemented the findings from here specific to adding a square image. image-generator is updated to .NET 8 and now outputs a square image as well as a rectangular image. It’s not clear which will be chosen considering a bunch of the og:image checking sites only load either the rectangular image or the square image.

    In fact, the output can be seen on this very page under View source > head:

    xml
    <meta name="twitter:image" property="og:image" content="https://staffordwilliams.com/assets/cards/2024-03-10-blog-square-image.png"> <meta property="og:image" content="https://staffordwilliams.com/assets/cards/2024-03-10-blog-square-image.png"> <meta property="og:image:width" content="4000"> <meta property="og:image:height" content="2000"> <meta property="og:image" content="https://staffordwilliams.com/assets/cards/2024-03-10-blog-square-image-square.png"> <meta property="og:image:width" content="2000"> <meta property="og:image:height" content="2000">

    There’s a good chance the first image should be of the form factor 1200x630, but I’ll see in the coming weeks how different sites and apps render it.

    Update 2024-03-12

    This was promptly reverted once I posted to discord and saw this:

    discord showing both og

    I’ll have to test on a dev site what this looks likes across platforms.

  • v3.0 - Dropping micro.blog

    After a year of integrating with micro.blog to host my devlog entries I’ve decided it’s more hassle than it’s worth. The benefits of micro blog was the ability to post outside my git environment and have posts auto-tweeted.

    Integrating proved difficult due to issues with CORS. Recently a Micro.blog server upgrade conflicted with my Cloudflare proxy meaning I would need to disable the rpoxy for Micro.blog to reestablish an HTTPS certificate (this would also break the CORs issue), and then re-enable it.

    I decided to reduce the dependency on Micro.blog and have migrated the devlog into a collection within my own jekyll-generated site. This gives me the opportunity to have further control over the content and structure, for example the devlog permalinks which are a Jekyll plugin i’ve written in ruby:

    ruby
    Jekyll::Hooks.register :devlog, :pre_render do |page| permalink = "devlog/#{page.data["tags"].first}/#{page.data["version"]}/" page.data["permalink"] = permalink end
  • v2.40 - Devlog

    After posting some updates on garage I realised that I often have content that sits somewhere between blogging and note taking but I don’t end up writing it because it sits in neither. The result of this is that I’ve integrated micro.blog into my site via a devlog section on the homepage.

    Micro.blog takes care of twitter cross-posting and I’ve edited its theme to look similar to staffordwilliams.com. As the rest of my site is static generated, I pull the content into the homepage via RSSParser. You can see the code in the source for index.html.