Every published post got a real, generated social-share card — 1200×630, built at build time with satori and resvg instead of the Chrome-based pipeline used everywhere else, specifically because that pipeline doesn’t run on the actual deploy server. Getting there took tracking down a font-format mismatch and a path bug that only showed up in the real static build, not in dev.

The very next entry closed the gap that shipping left standing: every non-post page still had no social card at all. A single default card, reusing copy that already existed elsewhere on the site rather than inventing new marketing lines, closed it — and building it surfaced that the per-post generator’s layout tree was about to get copy-pasted a second time, so it got pulled into one shared function instead.

Rung 2 of the GitHub on-ramp, left unmounted since the previous chapter, finally closed: the giscus app got installed and a Discussion category created, and rather than route through a third-party config form, the two IDs the comments component needed got queried directly from GitHub’s own API.

/newsletter — a dead link since the newsletter’s chrome first shipped — went live: a hero with a real subscribe form, and an archive section reading from the still-empty newsletter collection, which turned up a real bug where an empty content-collection directory throws instead of just returning nothing.

Main takeaways

  • Choosing a build tool isn’t just about what works locally — it has to actually run wherever the site deploys.
  • The same gap (no page-specific social description) showed up twice in a row — usually the signal it’s stopped being “not yet” and started being an actual decision to make.
  • Once real objects already exist, querying their real IDs directly beats routing through a third-party config generator built for the general case.
  • An empty content collection isn’t automatically an empty array — that has to be handled explicitly.

What I got wrong

  • No page, post or otherwise, has a real page-specific social description yet — same gap, twice, still open.
  • The build-time check for comments proves the HTML is correct but not that the comment widget itself resolves it — that only gets verified once a real post is live at the real URL.