I Built a Link Preview API — Here's What I Learned About Open Graph
Link previews seem simple until you actually build something that generates them reliably. I spent weeks digging into how platforms parse Open Graph metadata, and I kept running into the same category of problems: missing images, wrong fallbacks, cached bad data. Here is what surprised me.
What Link Previews Actually Are (And Why They Break)
When you paste a URL into Slack or Twitter, the platform fetches that page, reads the <meta> tags in the <head>, and renders a card. The Open Graph protocol, originally developed by Facebook, defines the standard tags most platforms follow: og:title, og:description, og:image, and og:url.
The reason previews break so often comes down to a few recurring patterns:
- The
og:imagetag is missing entirely - The image URL is relative instead of absolute
- The image dimensions are wrong and the platform rejects it silently
- The metadata exists but the page blocks crawlers with a bad
robots.txtor a JavaScript render wall
That last one is brutal. If your content is rendered client-side and you have no SSR or prerendering, most crawlers will fetch an empty shell and your preview will be blank.
The og:image Requirements Most Devs Skip
I see this constantly. Developers add an og:image tag, the preview still looks broken, and they cannot figure out why. The requirements are stricter than the documentation implies:
- Dimensions should be 1200x630 pixels. Facebook and LinkedIn will downscale, but if you go too small (under 200x200) they ignore the image completely.
- File size should stay under 1MB. Larger images may time out during the crawl window.
-
The URL must be absolute.
/images/preview.pngwill not work.https://yourdomain.com/images/preview.pngwill. - No SVGs. Almost no platform will render an SVG as a preview image. Use PNG or JPEG.
How Twitter Cards Differ From Open Graph
Twitter does read OG tags as a fallback, but it has its own system called Twitter Cards, and the twitter:card type changes how everything renders.
The two types you actually care about are summary and summary_large_image. If you use summary, Twitter shows a small thumbnail beside the text. If you use summary_large_image, you get the full-width banner image. Most developers want the large image but forget to set the tag, so they get the small thumbnail and wonder why it looks wrong compared to LinkedIn.
You also need twitter:title and twitter:description even if you already have the OG equivalents. Twitter will use OG as a fallback, but being explicit is more reliable.
The og:description Fallback Chain
When og:description is missing, platforms do not just leave it blank. The fallback chain typically goes:
-
og:descriptionmeta tag - Standard
meta name="description"tag - First paragraph of visible body text
Knowing this means you can usually ensure something reasonable shows up even on pages that have not been fully optimized.
The One Gotcha That Bit Me Hard
If og:url does not match the canonical URL of the page, platforms will cache the preview against the wrong URL. I had a staging URL leak into production metadata once and spent an embarrassing amount of time wondering why the preview was showing old content. Always set og:url explicitly to the canonical version.
Parsing all of this reliably across different platforms, redirect chains, and malformed HTML is exactly the kind of work that sounds quick and turns into a week of edge cases. I use what I built in production at LinkPreview API. It handles the messy parts of parsing OG data so you do not have to: https://rapidapi.com/ben-eI6jno4PU/api/linkpreview1
Top comments (0)