fix missing og:image on edra link cards
Created by: jedmund
Summary
- harden
/api/og-metadatascraping: twitter:image / image_src fallbacks, relative→absolute image url resolution, realistic browser UA, 8s fetch timeout, and a short 5-min TTL when image is missing so transient failures self-heal instead of sticking for 24h - enrich urlEmbed nodes at post save time so the saved content is the source of truth — immunizes against the editor race where the user hits save before the async metadata fetch completes
- editor UX: swap onMount for an
$effectthat re-runs on url change, add loading skeleton + retry affordance, and guard against stale writes with a generation counter
Why
a universe post with a valid og:image was rendering a blank link card. manually running extraction against the target html succeeds, so the scraper isn't the issue — the node was persisted with empty attrs, either because the user saved before the client fetch completed or because a transient failure got cached for 24h. the public page never re-fetches.
Test plan
-
GET /api/og-metadata?url=https://collectivefutures.blog/design-was-never-the-bottleneck/&refresh=truereturns the ghost-hosted og:image inimage -
fetch a 404 url, confirm null-image response cached for 5 min not 24h ( redis-cli TTL og-metadata:...) -
paste a url in the editor and save within ~200ms — the saved post still has imagepopulated (write-path enrichment filled it server-side) -
pick a url that serves twitter:image but not og:image (e.g. many x.com links) — image populates -
construct a page with <meta property="og:image" content="/img.png">— absolute url comes back -
throttle /api/og-metadataor point at a hanging url — skeleton + error state + retry button render and recover -
edit a url in an existing embed — old metadata is replaced and a late response from the previous url can't clobber the new one
Backfill
existing posts with blank link cards will re-populate by opening the post in the admin editor and re-saving (the write path will enrich). no migration needed.