I built an OG image generator — send it a title, a description, optionally a header image, and it returns a 1200x630 PNG for social preview cards. My test titles were strings like "My New Tool" and "Release Notes v2". Gorgeous.
Then I fed it a real blog post headline, 60+ characters. HTTP 200, image rendered — and when I checked how it looked in an actual link preview, the last third of the headline was missing. Not overlapping, not squeezed. Just absent, cleanly cut at the right edge of the canvas.
Root cause: a rasterizer is not a browser. In HTML, long text wraps. On a canvas, text is painted as a single line from its anchor point, and anything past the canvas boundary is silently clipped. No error, no warning, 200 OK with a broken card. All my tests used short strings, so I never hit it until a real-world length came through.
The fix turned it into a small text layout engine:
- Measure the title string with the actual font at the actual draw size
- Split on spaces and greedily fill lines while the measured width fits the content box
- Cap line count (3 for titles), ellipsis-truncate any overflow
- Repeat for the description, then vertically center the whole block
One subtle bug inside the fix: I measured with a fallback font before the real one finished loading, so wrap points landed early and lines broke in weird places. Measure and draw must use the same face at the same size, every single time.
The 60/120 character caps in the API are just a backstop now — the measured wrapping does the real work. That reworked version is the OG image generator I run at https://x402.freeq.one/tools/og_image_generator.html.
The general lesson: any tool that renders text onto a fixed-size image is secretly re-implementing a layout engine. Browsers give you reflow for free; a drawing context gives you nothing. And the failure mode is the worst kind — silent truncation that only appears at exactly the input sizes real users write, which your tests never covered.
Top comments (0)