Dev.to AI 🤖 Ai 👁 0 📖 1 min read

My OG image generator rendered blank cards for titles with one specific character

Built a social-card generator that takes a title, a description, and an optional header image, and spits out a 1200x630 PNG. Simple enough. Shipped it, watched it work for a week, then got a bug report: every card for ti

Built a social-card generator that takes a title, a description, and an optional header image, and spits out a 1200x630 PNG. Simple enough. Shipped it, watched it work for a week, then got a bug report: every card for titles containing an ampersand came back as a solid background with no text.

The culprit was the text-measurement path. I was using PIL's default font for layout — measuring string width to decide wrapping and font size. PIL's ImageFont.load_default() doesn't do font fallback, and more importantly I was passing the raw title string into a drawing context that still had HTML-style entity assumptions baked in from an earlier iteration. A title like Q&A Session was being interpreted as an entity reference, silently producing an empty string for the draw call. No exception, no log line, just a blank card.

The fix was boring and correct: escape before measuring, never assume the input is pre-sanitized. html.escape(title) before any layout math, then draw the escaped string. I also added a guard that refuses to render if the measured text width collapses to zero — fail loudly instead of shipping a blank image.

The lesson I keep re-learning: image-generation APIs fail silently in ways text APIs don't. A blank PNG is a valid response. Your monitoring has to check pixel content, not just HTTP 200.

Packaged at https://x402.freeq.one/tools/og_image_generator.html

📰 Read the original article on Dev.to AI

Originally published by Dev.to AI. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.