Use 1200×630 pixels (1.91:1 aspect ratio) as the universal default OpenGraph image size in 2026. It renders correctly on Facebook, LinkedIn, Slack, Discord, iMessage, WhatsApp, and Telegram, and falls back acceptably on X. Go to 1200×675 (16:9) only if X is your primary channel.
TL;DR
- Ship one 1200×630 PNG (1.91:1) and declare og:image:width/og:image:height to match.
- Keep it under 1 MB — WhatsApp soft-caps around 300 KB and silently downgrades larger images.
- Add
twitter:card=summary_large_imageor Discord renders a tiny 80×80 thumbnail instead of the large embed. - X accepts 1200×630 (crops to 16:9) up to a hard 4096×4096 / 5 MB ceiling; 1200×675 is its native shape.
- Put the headline and logo in the center 66% — every platform crops the edges differently.
What is the safest universal OpenGraph image size?
1200×630 is a 1.91:1 aspect ratio. It was defined by Facebook in its sharing best practices documentation around 2013, and every other unfurler adopted the same shape to match the dominant platform. Even X — which prefers 16:9 — renders 1200×630 correctly, just with a small vertical crop.
Why this exact size? 1200×630 hits the Facebook minimum of 600×315 at 2× density, is large enough to look crisp on retina screens, and small enough to stay well under platform file-size limits (Facebook 8 MB, X 5 MB, LinkedIn 5 MB). It's the same image you point both og:image and twitter:image at — see the OpenGraph meta tags guide for the full tag set.
What are the per-platform image sizes in 2026?
- Recommended: 1200×630, 1.91:1
- Minimum: 200×200 (rejected below this)
- Warning threshold: 600×315 (shown as "may render poorly")
- Max file size: 8 MB
- Mobile crop: shows full 1.91:1, no crop
- Recommended: 1200×627, 1.91:1 (LinkedIn's published number; 1200×630 works identically in practice)
- Max file size: 5 MB
- Mobile crop: 1.91:1, trimmed edges on narrow viewports
- Cache: 7 days — use Post Inspector to force re-scrape after changes
X (summary_large_image)
- Recommended: 1200×675, 16:9
- Minimum: 300×157; maximum: 4096×4096
- Max file size: 5 MB
- Accepts: PNG, JPEG, WebP, GIF (static first frame)
- If you supply 1200×630, X crops a thin strip from top and bottom
X (summary)
- Recommended: 144×144 minimum, square (1:1)
- Shown as a small thumbnail next to text — use only for compact cards
Slack
- Recommended: 1200×630, 1.91:1
- Max file size: 5 MB
- Cache: 24 hours
- Requires a valid Content-Type header on the image response
Discord
- Recommended: 1280×640, 2:1
- Also accepts: 1200×630, 1.91:1
- Max file size: 8 MB
- Defaults to an 80×80 thumbnail unless twitter:card=summary_large_image is present (see below) — landscape og:image:width/height help but are less reliable on their own
- Older desktop clients reject WebP — use PNG or JPEG
iMessage
- Recommended: 1200×630, 1.91:1
- Max file size: 5 MB
- Square-crops to a tile on the iOS lock screen, so keep key content centered
- Recommended: 1200×630, 1.91:1
- Soft cap ~300 KB — larger images are sometimes downgraded or skipped
- Requires og:image to be absolute HTTPS; HTTP is silently ignored
Telegram
- Recommended: 1200×630, 1.91:1
- Max file size: 5 MB
- Honors og:image:width and og:image:height for layout before the image finishes downloading
Why does aspect ratio matter more than pixel count?
Every platform scales the image to fit its preview card. What it can't fix is the aspect ratio — if you supply a square image to Facebook, it letterboxes or crops heavily. Key content (headline, logo, key visual) should live in the center 66% of the image to survive every platform's crop.
X crops a 1200×630 image top and bottom to hit 16:9. Slack on mobile sometimes square-crops to a thumbnail when space is tight. iMessage on lock screen always square-crops. Designing with a center-safe zone avoids surprises.
Why does Discord show a small thumbnail instead of a large image?
Correct size, correct file, still a tiny 80×80 thumbnail squeezed to the right of the text — this is the most common "my OG image is wrong" report for Discord, and dimensions alone won't fix it. Discord defaults to the thumbnail layout and only switches to the large embed when a signal tells it the image is the point of the unfurl. The single reliable trigger is the Twitter card tag: Discord reads <meta name="twitter:card" content="summary_large_image"> even though the tag is named for a different platform.
Landscape og:image:width / og:image:height nudge Discord toward the large format too, but on their own they're inconsistent — ship the twitter:card tag and treat the dimension tags as backup. If the wrong card is already cached, edit the message or repost the link; Discord re-fetches and re-serves the image through its own CDN. The same missing-tag pattern is the root cause behind most of the cases in OpenGraph image not showing.
Which image format should you use: PNG, JPEG, or WebP?
| Format | Best for | Compatibility |
|---|---|---|
| PNG | Graphics with text, logos, UI screenshots | Universal |
| JPEG | Photos, gradients, full-bleed imagery | Universal |
| WebP | Smaller file size for the same quality | Breaks on older Slack and Discord clients |
| GIF | Not recommended — first frame only, wastes bytes | Universal but inefficient |
| AVIF | Newer format, tiny files | Not supported by most unfurlers yet |
Recommendation: PNG for anything with text (crisp edges), JPEG for photos. Skip WebP and AVIF until the ecosystem catches up.
What are the per-platform file size limits?
- Facebook: 8 MB hard cap
- X: 5 MB hard cap
- LinkedIn: 5 MB hard cap
- Discord: 8 MB hard cap
- WhatsApp: 300 KB soft cap (above this, downgrades or skips)
- Practical universal target: under 1 MB for fast unfurls and no surprises
How do you generate dynamic OpenGraph images with Satori?
If you have a lot of pages (blog posts, user profiles, product pages), generating OG images by hand is a chore. The modern approach is to render them programmatically with Satori — Vercel's library that turns JSX into SVG, then rasterises to PNG. It runs at the edge in Vercel, Cloudflare Workers, or Node.
import satori from 'satori';
import { Resvg } from '@resvg/resvg-js';
const svg = await satori(
<div style={{ display: 'flex', background: '#0b0d0f', width: 1200, height: 630, color: '#fff' }}>
<h1 style={{ margin: 'auto', fontSize: 72 }}>Hello, OpenGraph</h1>
</div>,
{ width: 1200, height: 630, fonts: [{ name: 'Inter', data: interBuffer, weight: 700 }] }
);
const png = new Resvg(svg).render().asPng();Two constraints to know: Satori uses flexbox only (no grid), and the WASM bundle for Resvg is ~6 MB, which won't fit in strict edge runtimes. For Cloudflare Workers, generate at build time and ship PNG assets — that's the approach env.dev itself uses.
How do you test OpenGraph images across platforms?
Chrome DevTools' device mode shows how your preview will look, but the ground truth is always the platform's own validator. Use the Facebook Sharing Debugger and LinkedIn Post Inspector for authoritative rendering. For Slack, Discord, and iMessage: paste the link into a test channel or DM to yourself.
References
- The Open Graph protocol — the canonical og:image spec, including og:image:width and og:image:height.
- Facebook: recommended image sizes for sharing — the 1200×630 / 1.91:1 / 8 MB numbers come from this page.
- LinkedIn: making content shareable — confirms 1200×627, 1.91:1, 5 MB cap, and the <401 px thumbnail rule.
- Slack: unfurling links in messages — how Slack crawls and previews og:image, including app-driven custom unfurls.
- Satori (Vercel) — JSX-to-SVG renderer for generating OG images at the edge.
Ready to implement? The Meta Tag Generator produces a full tag set with the right og:image:width / og:image:height declarations, and the OpenGraph cheatsheet is the one-page reference.