Open Source OG cards, and the space that wasn't there
The Open Source section of this site shipped without proper social cards. Every link to it fell back to the site’s generic default OG image, the same picture whether you shared the index or a specific package’s detail page. The fix was to generate a real card per page, using the site’s own OG card generator to do it. Dogfooding, basically.
The design was already sitting there
The site already has a terminal-window card design for its default OG image: green glow text, a fake zsh prompt, a macOS-style title bar. I didn’t need a new visual language, just a new command line. The index card got $ ls @vdaluz/*. Each package card got $ npm install @vdaluz/<name> with the package name swapped into both the command and the title bar.
Wiring it in was mechanical: two new markup functions, a few more lines in the prebuild script that already generates the default card, the Deep Cut Atlas card, and blog post cards. Five new PNGs, five new image props on the relevant page files. I expected that to be the whole issue.
The space that wasn’t there
I opened the generated PNGs to eyeball them before committing, since a build succeeding doesn’t mean a design looks right. The astro-opt-in-analytics card read npm installavdaluz/astro-opt-in-analytics - “install” and the package name run together with no space, and the “a” in “@vdaluz” rendering without its @ visible because the two overlapped. The index card had the same thing: lsavdaluz/* instead of ls @vdaluz/*.
My first assumption was a typo in my own markup. It wasn’t. The space was right there in the source, a literal character between “install” and the styled span holding the package name. Then I looked at the existing default card, the one that’s been live in production this whole time, and found the same bug already shipped: ”./run—software” instead of ”./run —software”, “ImperfectSystems” instead of “Imperfect Systems.” Nobody had noticed, because nobody had looked that closely at a card that already worked well enough not to draw attention.
The actual cause: satori-html collapses a trailing whitespace text node when it sits right before an inline-styled <span> inside a flex container. A literal space character in the markup doesn’t survive if a styled element is the next sibling. The fix is to stop relying on that space existing at all and give the following span an explicit margin-left. Once I did that, both new cards rendered exactly as designed.
What I did with it
I fixed it in the two new files right away and opened a separate low-priority ticket for the pre-existing default and blog-post cards, since that bug predated this work and fixing it there wasn’t this issue’s job. Then, later the same session, I circled back and fixed those too. By that point the pattern and the fix were already understood, so it was a five-minute change rather than new investigation. Filing it separately first, then doing it once I had a spare minute, kept the original scope honest instead of quietly growing into “OG cards, day two.” I also flagged the satori-html quirk in the shared package’s own gotcha notes, since it’ll bite the next card design that reuses this layout pattern.
Lesson
“The build passed” and “the file exists” are not the same claim as “the thing looks right.” I could have shipped five cards with a rendering bug and never known, because nothing in the pipeline - astro check, the build, even the file existing on disk - inspects what’s actually inside a generated image. The only thing that caught it was opening the PNG, the same way opening the actual pixels has been the thing that fixed my mental model more than once.
Related reading
Two screenshot pipelines that look alike and aren't
Sibling folders, near-identical names, completely different jobs - plus a device bezel I mistook for a compositing bug, and a resolution downgrade worth naming out loud.
The filter pills existed, just not where anyone could find them
Per-project filtered views with a nice pill nav - reachable only from homepage cards. The main /blog index, where everyone actually lands, had no way in at all.
The CTA that pointed at the wrong dev log
The only call to action on the Deep Cut Atlas page linked to the whole unfiltered blog - a link that worked, returned 200, and quietly sent everyone to the wrong place for weeks.