Social cards in pure Rust: no headless Chrome
Cloud Cost Analyzer (CCA) lets you share a read-only scan as a link. Someone drops that link in Slack or on LinkedIn, and instead of a bare URL I wanted it to unfurl into a proper card: the brand mark, the monthly savings we found, the number of findings. That was two separate problems. Figuring them out took me somewhere I didn't expect, because neither one wanted a headless browser, but both needed a card. One of them even ate an afternoon because the fonts wouldn't cooperate. Here's the whole thing. The dashboard is a single-page app, rendered entirely in the browser ( ssr: false ). That's fine for humans. It's not fine for the crawlers Slack, LinkedIn, and X send at your link, because those don't run JavaScript. They fetch the HTML, find an empty shell with no og: meta tags, and give up. You get the bare URL in the Slack thread. So the crawler gets served something different. A CloudFront function reads the User-Agent on the viewer request: known bots get 302'd to a small server-rendered /embed page that carries the Open Graph tags and a meta refresh back to the real app. Humans get the SPA untouched. The crawler reads a fully-formed page with og:title , og:image , and friends; a human clicking the same link lands on the interactive dashboard. This is user-agent-based dynamic rendering for social crawlers, not SEO cloaking. The /embed page carries the same title and numbers a human would see, and it meta refresh es straight to the real app, so nobody is handed content that contradicts what the link actually shows. That's the easy half, structurally. Now comes the picture, which is where I had a choice to make. The default path for "turn some text on a branded background into a PNG" is to render HTML in headless Chrome and screenshot it. It works. It also means shipping a browser alongside your service, keeping it patched, and paying its cold-start and memory cost on a code path that exists only to make links look nice. In a Rust backend that's a lot of weight to