If you only remember one thing: make your og:image 1200 × 630 pixels, keep it under about 1 MB, serve it over HTTPS at an absolute URL, and declare its width and height. That single image works on every major platform. Everything below is about why that number, what each platform does to your image once it has it, and the specific cases where one image is not quite enough.
The Baseline: 1200 × 630
1200 × 630 is a 1.91:1 aspect ratio, which is the shape Facebook standardised on and every other platform designed around. It is large enough that no major platform upscales it — upscaling is what makes previews look soft — and small enough to stay well inside file-size limits.
The constraints that produce that number:
- Minimum for a large card: 600 × 315. Below this Facebook and LinkedIn fall back to a small square thumbnail beside the text instead of the full-width image.
- Absolute floor: 200 × 200. Anything smaller is rejected outright and the card renders with no image at all.
- Recommended: 1200 × 630, which is 2× the large-card minimum and looks sharp on high-density displays.
- Upper bound: there is no hard pixel ceiling, but past about 2400 × 1260 you are paying file size for no visible gain.
What Each Platform Does With It
| Platform | Displayed ratio | Reads | Behaviour with a 1200 × 630 image |
|---|---|---|---|
| 1.91:1 | og:image | Displays as-is, no crop | |
| 1.91:1 | og:image | Displays as-is, no crop | |
| X (Twitter) | 2:1 | twitter:image, falls back to og:image | Crops slightly top and bottom |
| Slack | Variable | og:image | Scales to fit, no crop |
| Discord | Variable | og:image | Scales to fit, no crop |
| ~1.91:1 | og:image | Displays as-is; small previews use a square crop | |
| iMessage | Variable | og:image | Scales to fit |
| 2:3 preferred | og:image | Works, but vertical images perform far better |
The only platform that meaningfully crops a 1.91:1 image is X, and it takes a thin slice off the top and bottom to reach 2:1. That is what the safe zone below is for.
The Safe Zone
Because X crops vertically and small WhatsApp previews may crop to a square, anything essential — logo, headline text, a face — should sit inside a central region rather than at the edges.
1200 x 630 canvas
+----------------------------------------------------+ <- top ~40px may be cropped by X
| |
| +------------------------------------------+ |
| | | |
| | SAFE ZONE | |
| | ~1080 x 550 centred | |
| | keep text and logos here | |
| | | |
| +------------------------------------------+ |
| |
+----------------------------------------------------+ <- bottom ~40px may be cropped by X
Square crop (WhatsApp thumbnails) takes the centre 630 x 630 —
anything critical should survive that too.A practical rule: keep text within the middle 80% horizontally and the middle 85% vertically, and assume the far left and right thirds may vanish in a square crop.
Text in the Image
Cards render small — often 500 px wide in a feed, less on mobile. Text that looks comfortable in your design tool becomes unreadable at display size.
- Minimum ~60 px font size on a 1200 × 630 canvas for anything that must be read.
- Six words or fewer. The card already has a title and description beneath it — the image does not need to repeat them.
- High contrast. Thin type over a photograph disappears at thumbnail size.
- Do not duplicate
og:titlein the image. It reads as a stutter when both are visible.
File Size and Format
| Property | Recommendation | Notes |
|---|---|---|
| File size | Under 1 MB | Facebook accepts up to 8 MB, but large files time out during scraping |
| Format | PNG or JPEG | Universally supported |
| WebP | Avoid | Support is inconsistent across scrapers |
| SVG | Never | Not supported by any major platform |
| Animated GIF | Avoid | Rendered as a static first frame at best |
| Transparency | Avoid | Composited onto white or black unpredictably |
| Protocol | HTTPS | Mixed content is blocked outright |
JPEG for photographic images, PNG for flat colour and text. If your build pipeline serves WebP by content negotiation, make sure the og:image URL returns a JPEG or PNG to crawlers specifically — a scraper receiving WebP may silently drop the image.
Declaring Dimensions
og:image:width and og:image:height are optional and worth setting on every page. They let the platform reserve the right layout before it has finished downloading the image.
<meta property="og:image" content="https://example.com/og/article.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta property="og:image:alt" content="A bar chart showing build times dropping from 14 to 4 minutes">
<meta property="og:image:type" content="image/png">Without them, the very first share of a URL frequently renders with no image while the scrape is still in flight — the platform has an image URL but no idea what shape it is, so it shows the text-only layout and fixes itself only on a later view. Declaring the dimensions removes that race entirely.
Per-Platform Overrides
One image is enough for almost everyone. Two cases justify a second:
X, if you want a different crop. twitter:image overrides og:image on X only, so a 1200 × 600 version avoids the vertical crop entirely:
<meta property="og:image" content="https://example.com/og/article-1200x630.png">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:image" content="https://example.com/og/article-1200x600.png">Pinterest, if it matters to your audience. Pinterest strongly favours vertical imagery at 2:3 (1000 × 1500). There is no Pinterest-specific meta tag for this — you would use data-pin-media on an in-page image rather than an og: tag.
Note that twitter:card itself matters more than the image size on X: without summary_large_image, X shows a small square thumbnail regardless of what you supply.
Multiple og:image Tags
The protocol permits several og:image tags, with the first treated as primary. In practice this causes more problems than it solves — some scrapers pick the first, others the last, and a CMS that injects a default image alongside yours produces exactly this situation.
# Check for accidental duplicates in the served HTML
curl -sL https://example.com/page | grep -c 'property="og:image"'
# More than 1 usually means a plugin or theme is adding its ownPublish exactly one og:image unless you have a specific reason not to. If a checker reports duplicates, that is the cause of an unpredictable preview.
Generating Images at Scale
Hand-designing a card per article does not scale. The common approach is templated generation — a background, the title, and a logo composited at request time or build time:
# Next.js — dynamic OG images via the built-in ImageResponse API
# app/og/route.jsx (App Router)
import { ImageResponse } from 'next/og';
export function GET(request) {
const title = new URL(request.url).searchParams.get('title') ?? 'Example';
return new ImageResponse(
<div style={{ display: 'flex', width: '100%', height: '100%',
alignItems: 'center', justifyContent: 'center',
fontSize: 64, background: '#0b1020', color: 'white' }}>
{title}
</div>,
{ width: 1200, height: 630 }
);
}Whatever generates them, the output contract is the same: 1200 × 630, under 1 MB, PNG or JPEG, at a stable absolute HTTPS URL. Cache the result — platforms fetch the image separately from the page, and an image endpoint that recomputes on every scrape will eventually time out.
Checking What You Actually Serve
# What image URL is declared?
curl -sL https://example.com/page | grep -i 'og:image'
# Is it reachable, and what are its type and size?
curl -sI https://example.com/og/article.png | grep -iE 'http/|content-type|content-length'
# Real pixel dimensions of the file
curl -sL https://example.com/og/article.png -o /tmp/og.png && file /tmp/og.pngfile reports the true dimensions, which is the fastest way to catch a mismatch between your declared og:image:width and reality. The Open Graph Checker does all of this in one pass and previews the card on four platforms.
Frequently Asked Questions
What is the best og:image size?
1200 × 630 pixels. It is a 1.91:1 ratio, it is sharp on high-density displays, no major platform upscales it, and it comfortably clears every file-size limit. Use it unless you have a specific reason to deviate.
What is the minimum og:image size?
200 × 200 is the absolute floor — smaller images are rejected and the card renders with no image. For the large card layout rather than a small thumbnail, you need at least 600 × 315.
Do I need a separate image for Twitter/X?
No. X falls back to og:image when twitter:image is absent. A separate 1200 × 600 version only avoids the small vertical crop, which matters if your design has content near the top or bottom edge. Setting twitter:card="summary_large_image" is far more important.
Why does my image look blurry in the preview?
Usually because the real image is smaller than the platform's display size and is being upscaled — or because your declared og:image:width and og:image:height overstate the actual file. Check the true dimensions with file and make sure the declared values match.
Can I use a WebP or SVG image?
SVG never works — no major platform supports it. WebP support is inconsistent across scrapers, so a WebP og:image may render on some platforms and vanish on others. Serve PNG or JPEG at the og:image URL specifically, even if the rest of your site uses WebP.
Does the image need to be on the same domain as the page?
No, but it must be an absolute HTTPS URL that is publicly reachable — no auth, no hotlink protection, and not blocked by robots.txt. A CDN on a different hostname is fine.
I changed the image but the old one still shows. Why?
Platforms cache scrape results for hours or days, keyed by URL. The fix is correct but invisible until you force a re-scrape in the platform's debugger. See How to Fix a Link Preview Not Showing.