Open Graph tags: how link previews actually work.

Paste a link into Slack, iMessage, or LinkedIn and a little card appears — title, description, image. That card is not magic and it's not scraped from your page's visible content: it's assembled from a handful of meta tags by a crawler that fetched your URL the moment it was shared. When the card looks wrong, one of those tags is wrong. Here's the whole pipeline.

Open Graph started as a Facebook project in 2010: a small vocabulary of <meta> tags, documented at ogp.me, that lets a page declare how it wants to appear when shared. It worked, everyone else adopted it, and today one set of tags drives previews across most chat apps and social platforms — which is exactly why it's worth getting right once.

What happens when you paste a link.

The moment a URL is shared, the platform's crawler fetches it — a plain HTTP request with a bot user-agent — and parses the response's <head> for meta tags. Three properties of this fetch explain most preview bugs:

It's mostly JavaScript-blind. Preview crawlers generally read the raw HTML the server returns. Tags injected client-side by a framework after load are invisible to many of them — the single biggest cause of "works in the browser, blank in Slack." The tags need to be in the served HTML.

It happens from the platform's servers. If your page is behind a login, a paywall, an IP allowlist, or a firewall rule that blocks bots, the crawler sees a login page or an error — and so does the preview.

It's cached. Platforms keep the scraped result, often for days. Fix a tag and the old card keeps showing until you force a re-scrape with the platform's debugger tool.

The four tags that matter (plus two).

The Open Graph spec marks four properties as required, and two more are so widely displayed they're effectively required too:

<meta property="og:title"       content="Your headline">
<meta property="og:type"        content="website">          <!-- or "article" -->
<meta property="og:image"       content="https://example.com/card.jpg">
<meta property="og:url"         content="https://example.com/page/">

<meta property="og:description" content="One or two sentences of summary.">
<meta property="og:site_name"   content="Your Site">

Two details punch above their weight. og:url should be the page's canonical URL — platforms use it to aggregate shares, so a page reachable at five URL variants consolidates into one card with one engagement count. And og:type changes how some platforms treat the link (article unlocks article-specific fields like published time); for most pages the honest choices are just website or article.

The image: sizes and rules.

The image makes or breaks the card, and it has real constraints:

Use an absolute URL. content="/card.jpg" is the classic mistake — some crawlers won't resolve relative URLs, and the preview silently drops the image. Always https://your-domain/....

1200 × 630 is the sweet spot. That's the size Facebook's documentation recommends for large cards, and its 1.91:1 shape is what most platforms crop toward. Ship that one size and you look intentional nearly everywhere; go dramatically smaller and platforms fall back to a tiny thumbnail card or none at all.

Design for the crop, not the full frame. Chat apps letterbox, round corners, and overlay text differently. Keep the message in the middle two-thirds, keep text large, and check it at thumbnail size.

Declare dimensions if the first share matters. og:image:width and og:image:height let a crawler lay out the card before it has downloaded the image — without them, the very first share of a fresh URL can render without its image on some platforms.

Twitter cards and other dialects.

Twitter (now X) has its own vocabulary using name="twitter:*" instead of property="og:*". Mercifully, it falls back to Open Graph for content — in practice you need one extra tag, plus one duplicate for strictness:

<meta name="twitter:card"  content="summary_large_image">
<meta name="twitter:image" content="https://example.com/card.jpg">

twitter:card is the one with no OG equivalent: it selects the layout, and summary_large_image is what makes the big full-width card instead of the small square thumbnail. Everything else — title, description — falls back to your OG tags. Other platforms are mostly OG-faithful: LinkedIn, Slack, Discord, WhatsApp, iMessage, and Telegram all read Open Graph, each with its own crop and cache quirks.

The practical set: six OG tags plus two Twitter tags — eight lines — cover essentially every platform. This site ships exactly that set on every page, and the Meta Tag Generator emits it ready to paste.

Why your preview isn't working.

Debugging previews is a short checklist, in rough order of likelihood:

1. The cache. You fixed the tags but the platform is showing its stored scrape. Run the URL through the platform's debugger (Facebook's Sharing Debugger, LinkedIn's Post Inspector) and force a refresh.

2. Tags not in the served HTML. View source — actual source, not the DOM inspector. If your og:* tags aren't in what the server sends, the crawler never sees them. Server-render them or pre-render the pages that get shared.

3. The image URL. Relative instead of absolute, HTTP on an HTTPS page, blocked by robots.txt, behind auth, or slow enough that the crawler gives up. Fetch the image URL yourself from a clean session and see what comes back.

4. Conflicting or duplicated tags. Two og:title tags (one from a template, one from a plugin) and platforms pick nondeterministically. One page, one set of tags.

5. The crawler is blocked. Aggressive bot rules or firewalls that 403 anything with a bot user-agent also 403 the preview crawlers.

What Open Graph is not: SEO.

A common conflation, worth untangling: Open Graph is for social and chat previews. Search engines have their own channels — the <title> element and meta name="description" for the results snippet, and structured data (JSON-LD, schema.org) for rich results. Google's documentation doesn't list OG tags among ranking factors; a page can have flawless OG and be invisible to search, or rank #1 with no OG at all (it'll just look shabby when shared).

The practical consequence is that a complete page head carries all three layers side by side — title/description for search, OG + Twitter for sharing, JSON-LD for rich results — describing the same content in three dialects. Repetitive, but each consumer reads only its own.

Takeaways.

The thing to remember: the preview card is built by a JavaScript-blind, cache-happy crawler from meta tags in your served HTML. Ship the six OG tags plus twitter:card and twitter:image, use an absolute 1200×630 image, point og:url at the canonical URL — and when a card looks stale, it's the platform's cache, not your deploy.

Link previews are one of those rare web features with a genuinely small, stable surface: eight lines of markup, one image, one debugging ritual. An hour of setup, and every link to your site starts pulling its weight.

Generate the full tag set in your browser.

The Meta Tag Generator takes a title, description, URL, and image and emits the complete, HTML-escaped set — SEO, Open Graph, and Twitter Card — ready to paste into your head. Entirely client-side, like everything else in the workshop.

Open the Meta Tag Generator
Tooly mascot

Made with love by a very serious person pretending not to be. Tooly McToolface is a workshop of free, client-side web tools. For the other half of a well-dressed page head, every favicon size, explained covers the icons, and URL encoding explains what happens to the URLs those cards point at.