og:image Sizes & Aspect Ratios by Platform

One image has to survive being cropped by a dozen different layouts. Here is the size that works everywhere, and what each platform actually does to it.


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.
Design at 1200 × 630, not largerDoubling to 2400 × 1260 does not improve rendering — platforms downscale to their own display size either way — and it pushes you toward the file-size limits that cause images to be dropped. 1200 × 630 is already retina-adequate for every card layout in use.

What Each Platform Does With It

PlatformDisplayed ratioReadsBehaviour with a 1200 × 630 image
Facebook1.91:1og:imageDisplays as-is, no crop
LinkedIn1.91:1og:imageDisplays as-is, no crop
X (Twitter)2:1twitter:image, falls back to og:imageCrops slightly top and bottom
SlackVariableog:imageScales to fit, no crop
DiscordVariableog:imageScales to fit, no crop
WhatsApp~1.91:1og:imageDisplays as-is; small previews use a square crop
iMessageVariableog:imageScales to fit
Pinterest2:3 preferredog:imageWorks, 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.

text
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:title in the image. It reads as a stutter when both are visible.
Test at actual sizeScale your image to 500 px wide and look at it. If you cannot read it on a phone at arm's length, neither can anyone scrolling a feed.

File Size and Format

PropertyRecommendationNotes
File sizeUnder 1 MBFacebook accepts up to 8 MB, but large files time out during scraping
FormatPNG or JPEGUniversally supported
WebPAvoidSupport is inconsistent across scrapers
SVGNeverNot supported by any major platform
Animated GIFAvoidRendered as a static first frame at best
TransparencyAvoidComposited onto white or black unpredictably
ProtocolHTTPSMixed 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.

html
<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.

Declared dimensions must be trueIf you claim 1200 × 630 and serve a 600 × 315 image, platforms lay out for the larger size and then upscale — producing a visibly blurry card. The tags describe the file; they do not resize it.

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:

html
<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.

bash
# 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 own

Publish 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:

Command
# 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

bash
# 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.png

file 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.

Related