Use 1200×630 px (1.91:1) for og:image — it renders as a large card on Facebook, LinkedIn, X, Slack and Discord. Add og:title, og:description, og:url, og:image and twitter:card = summary_large_image. Keep titles under ~60 characters, serve the image over HTTPS, and re-scrape with each platform's debugger after changes.
§1 · The five tags that cover 95% of shares
| Tag | Rule of thumb |
|---|---|
| og:title | ≤60-65 chars (Facebook/LinkedIn clip there; X clips ~70). Front-load the value. |
| og:description | 1-2 lines survive: ~55-200 chars depending on platform/device. First 55 must stand alone. |
| og:image | 1200×630, 1.91:1, JPG/PNG/WebP, <5MB, HTTPS, ABSOLUTE url. No SVG — X and Facebook won't render it. |
| og:url | The canonical URL — must match what you actually share or caches split. |
| twitter:card | summary_large_image for the big card; the ONE twitter: tag with no og: fallback. |
X/Twitter reads og:title/og:description/og:image as fallbacks — you do not need to duplicate them in twitter: variants unless you want different copy per platform.
§2 · Image sizes per placement
| Placement | Size / ratio | Notes |
|---|---|---|
| Universal large card | 1200×630 · 1.91:1 | The default. If you make ONE image, make this one. |
| X summary (small) | 1:1 square ≥144px | Only if you set twitter:card=summary instead of large. |
| WhatsApp/Telegram thumb | uses og:image | Square-ish crop in chat lists — keep the subject centered. |
| Discord | uses og:image, honors ratio | Also reads theme-color for the embed accent stripe. |
- A square (1:1) og:image gets cropped or letterboxed on Facebook/LinkedIn/Slack — don't fight the 1.91:1 grain.
- Keep text/logos inside the middle ~80%: platform crops nibble the edges, especially in mobile feeds.
- Insecure (HTTP) image URLs get refused by X and LinkedIn crawlers — HTTPS absolute URLs only.
See your card before you ship it: live preview on 5 platforms + warnings for truncation and image problems.
Open OG meta generator →§3 · When the preview won't update (cache debugging)
- Platforms cache the first scrape hard. Fixing your HTML does nothing until the cache re-scrapes. Use the Facebook Sharing Debugger, LinkedIn Post Inspector, or share with a
?v=2query string to force a fresh fetch (works on Slack/Discord too). - Check what the crawler sees, not what you see:
curl -A "facebookexternalhit/1.1" https://your.url— SSR/edge rules sometimes serve bots different HTML than browsers. - First share is slow-image? Some platforms show no image on the very first share because the scrape happens async — pre-warm by running the URL through the debugger before the real post.
§4 · FAQ
What size should an og:image be?
1200×630 (1.91:1), under ~5MB, HTTPS, absolute URL. It's the one size that renders large everywhere.
Why doesn't my preview update after changing tags?
Scrape caches. Re-run the platform debugger or append a query string to the URL. View-source being correct proves nothing about the cache.
Do I need twitter: tags if I have og: tags?
Only twitter:card. Everything else falls back to Open Graph.
Can og:image be an SVG?
No — X and Facebook won't render SVG cards. Export a PNG/JPG (we hit exactly this bug with our own hub's lobo image and swapped to a 1200×630 PNG).