Open Graph and social previews
og:* tags and Twitter cards are what makes a link unfurl into a card. The minimum set, the image rules, the debugger workflow.
You paste a link into Slack, iMessage, Twitter, LinkedIn, Discord. The link expands into a card with a title, a description, and an image. That card was not built by the messaging app — it was read from your page's <head>. The protocol is Open Graph (OG), and getting it right is the difference between a link that gets clicked and a link that gets scrolled past.
This lesson covers the minimum OG tags, the image rules nobody writes down, and the debugger workflow that catches mistakes before they hit production.
The minimum og: set
Open Graph is a Facebook-invented protocol that almost every social platform adopted. The tags are <meta> elements with property attributes prefixed og:.
<meta property="og:title" content="Sourdough season is back"> <meta property="og:description" content="Our wild-yeast loaf returns next Friday. Reserve a loaf or learn how the starter works."> <meta property="og:image" content="https://example.com/og/sourdough.jpg"> <meta property="og:url" content="https://example.com/sourdough-season"> <meta property="og:type" content="article">
That is the floor. Five tags, every one earning its place.
og:title— the title shown in the card. Often the same as<title>, but you can write a more share-friendly version. Drop the site name suffix; the card already shows the site.og:description— the description shown in the card. Same idea as<meta name="description">but tuned for social: short and grabby.og:image— the URL of the preview image. Absolute URL (withhttps://), not relative.og:url— the canonical URL of the page (lesson 7 covers canonical in depth).og:type— what kind of object this page is. Common values:website,article,book,profile,product.articleis right for blog posts and news.
Most social platforms also fall back to <title> and <meta name="description"> when the OG tags are missing — but the image almost always requires og:image. Without it, the card is title and description only.
Use absolute URLs in og:image and og:url. A relative path like /og/sourdough.jpg works on your page but breaks the moment a crawler fetches it from a different origin. Always include the protocol and domain.
Twitter cards, briefly
Twitter (now X) has its own card protocol: the twitter:* meta tags. It overlaps heavily with OG, and Twitter falls back to OG when the Twitter-specific tags are missing — so for most sites, OG is enough.
The two tags worth adding explicitly:
<meta name="twitter:card" content="summary_large_image"> <meta name="twitter:site" content="@dailybread">
twitter:card controls the card layout. summary_large_image is the modern default — a big image with title and description below. The older summary lays out as a small thumbnail next to text.
twitter:site is your site's Twitter handle. Optional but earns a small badge in the card.
For everything else (title, description, image, URL), Twitter reads OG tags. Save yourself the duplication.
The image is the headline
The OG image is the single most-clicked part of a card. People skim the image first, the title second. Get the image right and the rest follows.
A few rules:
Aim for 1200 × 630 pixels. That is 1.91:1, the aspect ratio every major platform crops to. Smaller images get blurry on retina; larger images load slowly without paying off.
Less than 1 MB. Some platforms refuse to fetch images over a certain size. JPEG at quality 80 is usually fine.
Make it readable as a thumbnail. The image is also shown small in some places (Slack inline previews, Discord embeds). Big text, high contrast, key info centered. A 14px label drowns at thumbnail size.
Brand it lightly. The image is the only place users see your visual identity in the unfurled card. A consistent OG image style across your site builds recognition.
Use a generated image when possible. Many sites generate an OG image per page from the page's title and a template — then the image always reflects the actual content. Next.js, Vercel OG, satori, and several CDN-based image services do this in two lines.
<meta property="og:image" content="https://example.com/og?title=Sourdough+season+is+back&author=Maya"> <meta property="og:image:width" content="1200"> <meta property="og:image:height" content="630"> <meta property="og:image:alt" content="A round sourdough loaf, with the post title overlaid">
The width and height tags help platforms reserve space before fetching. The alt is for screen-reader users — yes, social cards have alt text, and yes, you should write it.
A useful picture: the OG card is a small movie poster that ships with every link. The image is the visual; the title is the tagline; the description is the trailer. Get all three telling the same story and the link earns its click.
og:image is set to "/og/loaf.jpg". What's the most likely fix?The debugger workflow
Social platforms cache OG previews. Once your page has been shared, the platform has snapshotted the card. Edit your tags and the preview does not change — until you tell the platform to re-fetch.
Each major platform has a debugger:
- Facebook: Sharing Debugger (debugs OG, refreshes the cache).
- Twitter/X: Card Validator (no longer public for everyone, but still useful where available).
- LinkedIn: Post Inspector.
- Slack, Discord, iMessage: no public debugger; they re-fetch on a longer cycle.
The workflow:
- Add your OG tags. Deploy.
- Open the platform's debugger and paste your URL.
- Click "Scrape again" or "Refresh preview". The platform fetches the page fresh and shows you exactly what the card will look like.
- If something is wrong, fix the tags, re-deploy, re-debug.
For platforms without a public debugger (Slack, Discord, iMessage), the cache typically expires after a day or two. For testing right now, share the link in a private channel and see what comes back.
Add a query parameter (?v=2) to your URL when you need to bypass a stubborn cache during testing. The platform sees a "new" URL and fetches fresh. Once the cache clears, you do not need the parameter anymore.
A good rule: any time you change OG tags on a page that has been shared, run it through Facebook's debugger and click "Scrape again". That re-fetches across most platforms that share the cache (which is most of them).
og:image and og:title tags. You share the URL in Slack and the old preview still shows. What's the right next step?og:image at 3.5 MB. Some platforms display the card without the image. Why?<title> reads "How sourdough fermentation works · Daily Bread Bakery". What should og:title read?