An Open Graph image (OG image) is the picture a link shows when it is shared on LinkedIn, Facebook, X, Slack, Discord, WhatsApp or iMessage. You set it with one tag in the page's <head> — <meta property="og:image" content="https://example.com/og/post.png"> — and each platform's crawler downloads it the first time the link is shared. The size that works everywhere is 1200×630 pixels, as JPEG or PNG under 600 KB; the per-platform table has every documented limit.
The minimal tag set to copy
Paste this into the <head> of every page, with that page's own values:
<meta property="og:title" content="How we cut our image pipeline to 900 ms">
<meta property="og:description" content="Moving rendering off the request path and caching by content hash.">
<meta property="og:type" content="article">
<meta property="og:url" content="https://example.com/blog/image-pipeline">
<meta property="og:image" content="https://example.com/og/image-pipeline.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta property="og:image:alt" content="Title card: How we cut our image pipeline to 900 ms">
<meta name="twitter:card" content="summary_large_image">
Why each line is there:
| Tag | What it does |
|---|---|
og:title, og:type, og:url, og:image
|
The four properties the Open Graph protocol calls required |
og:description |
The line under the title; LinkedIn and WhatsApp list it as required |
og:image:width, og:image:height
|
Lets Facebook "render the image immediately without having to asynchronously download and process it" (Meta); Discord otherwise downloads the image just to measure it |
og:image:alt |
A description of the image, "not a caption"; ogp.me says a page with og:image should set it |
twitter:card |
Chooses X's card layout; summary_large_image is the big image above the title |
Open Graph uses property=, Twitter Cards use name=. Most parsers accept either, but following each spec avoids surprises.
How each platform reads it
When a link is pasted, the platform fetches the page's HTML, reads the tags, then fetches the image from its own servers. Apple states that Messages runs no JavaScript, and no other platform documents running it, so treat the HTML your server sends as all they see. What each one documents:
-
Facebook (crawler
facebookexternalhit) listsog:url,og:title,og:descriptionandog:imageas the basic tags (Meta), and the Open Graph properties must come before the first 1 MB of the page (Meta crawlers). -
LinkedIn says
og:title,og:image,og:descriptionandog:url"must exist" (LinkedIn Help). -
X reads its own
twitter:tags and falls back toog:title,og:descriptionandog:imagewhen one is missing. Withouttwitter:card, "a summary card may be rendered" — the small one with a square image (X cards markup, archived). -
Slack (
Slackbot-LinkExpanding) reads oEmbed, Twitter Card and Open Graph tags and caches the result for "around 30 minutes" (Slack). It does not honourrobots.txtfor unfurls. -
Discord reads
og:andtwitter:tags andtheme-colorfor the accent bar, shows a small image unlesstwitter:cardissummary_large_image, and gives the page 10 seconds (Discord). -
WhatsApp needs
og:title,og:description,og:urland an absoluteog:imageunder 600 KB, with the<head>inside the first 300 KB of HTML (Meta). - iMessage reads Open Graph tags, follows server redirects but not JavaScript ones, and wants images at least 900 px wide (Apple TN3156).
Two rules follow for developers: the tags must be in the HTML the server sends, and the image URL must be absolute and public — the crawler fetches it without your cookies.
og:image vs twitter:image
X has its own tags (Twitter Cards). twitter:card picks the layout, twitter:image the picture, twitter:title and twitter:description the text. The last three fall back to their Open Graph counterparts; twitter:card falls back only to the small summary card. So the usual set is og:image plus one line:
<meta name="twitter:card" content="summary_large_image">
Set twitter:image only when X should get a different picture from everyone else. The large card is 2:1 and the plain summary card crops the image to a square, so 1200×630 suits summary_large_image, not summary.
Common failures, and how to see them
Six common causes, each with a way to see it:
-
Relative image URL.
content="/og/post.png"works in a browser, not everywhere else: WhatsApp asks for an absolute URL, and Discord accepts a relative one only when it starts with/. Write the scheme and host every time. - The image answers 404, 403 or a redirect to a login page. The crawler is anonymous. Open the image URL in a private window; if you see anything but the image, so does the crawler. Hotlink protection and bot-blocking firewalls cause the same symptom.
- Tags added by JavaScript. A single-page app that sets meta tags after load risks showing nothing: Messages runs no scripts, and no other platform says it does. Render the tags on the server or at build time.
- Wrong size or file. Under 600×315 Facebook shows a small image; under 401 px wide LinkedIn shows a thumbnail; WhatsApp asks for under 600 KB. The size reference lists each platform's limits and has an in-browser check.
-
Tags too far down the page. Facebook reads Open Graph properties only in the first 1 MB, WhatsApp the first 300 KB. Put them near the top of
<head>, before large inline scripts or styles. - The old preview is cached. Fixing the tag does not change a card that was already fetched. Facebook caches images by URL, so give a new image a new URL and re-scrape the page in the Sharing Debugger. LinkedIn's Post Inspector refreshes its preview. Slack and Discord keep previews for about 30 minutes; X documents no refresh tool.
To see all of this at once, paste the page into the free OG Checker: it fetches the page like a crawler, lists missing or broken tags and previews the card on X, LinkedIn, Facebook, Slack and Discord. The debugging guide goes through each platform step by step.
What makes a good OG image
The image is shown at a few hundred pixels wide in a feed and smaller in chat apps, next to your title in plain text. So:
- Large type, few words. A title set at 60–80 px on a 1200-px canvas stays readable when scaled down; body-size text does not. Apple advises against text in preview images altogether, because Messages shows them at varying sizes.
- Keep it away from the edges. X's large card is 2:1, and how it crops other ratios is not documented. Keep the title and logo inside the middle 1200×600.
- Brand consistently. A logo or colour bar in the same place on every card makes your links recognisable in a busy feed.
- Small files. Our own 1200×630 text cards come out at 55–60 KB as JPEG; whatever you use, stay under WhatsApp's 600 KB.
How sites produce one image per page
A single site-wide image is fine for a homepage; for articles, products, docs pages and job posts, a per-page image with that page's title works better. The common ways to make them:
- By hand in a design tool — fine for a handful of pages.
-
At build time or in a job, with a headless browser (Puppeteer, Playwright) or a drawing library (Pillow, GD, Satori/
next/og). Free per image, but you maintain the renderer, fonts and memory. -
With an image API: you keep a template and send the page's fields, from your server or as a signed URL right in the
og:imagetag. Shareglint (disclosure: I build it) is one of these: 153 built-in 1200×630 templates, your own HTML and CSS, and a Free plan of 100 images a month — the API docs show the request. Others include Bannerbear, Placid and HTMLCSStoImage; see the comparison. - With a screenshot of the page itself — quick, but a desktop screenshot is the wrong shape and hard to read at thumbnail size; when screenshots make sense.
Framework walkthroughs: Next.js, Laravel, Rails, Django, WordPress and static sites.
FAQ
What is an OG image?
The image set in a page's og:image meta tag. Social networks and messaging apps show it in the preview card when someone shares a link to the page, next to the title and description from og:title and og:description.
Is og:image required?
The Open Graph protocol lists og:image among its four required properties, with og:title, og:type and og:url, and LinkedIn and WhatsApp both list it among the tags a preview needs. Without it most platforms show a text-only preview.
What size should an OG image be?
1200×630 pixels (1.91:1), JPEG or PNG, under 600 KB. That meets Facebook's recommendation, LinkedIn's 1200×627 minimum, X's card limits and WhatsApp's 600 KB limit.
What is the difference between og:image and twitter:image?
og:image comes from the Open Graph protocol and is read by almost every platform. twitter:image is X's own tag; X uses it when present and falls back to og:image when it is missing. Set twitter:card to summary_large_image too: without it X may render the small summary card.
Why does my old OG image still show?
Platforms cache previews. Facebook caches images by URL, so give a new image a new URL and re-scrape in the Sharing Debugger; LinkedIn's Post Inspector refreshes a preview; Slack and Discord keep one for about 30 minutes.
Originally published on Shareglint.
Top comments (0)