The edge function approach is a nice middle ground, since it only rewrites the head for crawler user agents and leaves the SPA untouched for everyone else. One gotcha is caching: Slack, LinkedIn and Facebook all cache the card aggressively, so testing with their debug tools and forcing a rescrape saves a lot of confusion. Setting og:image dimensions explicitly also helps some platforms render the large card on the first share.