og:image Not Showing? Fix Your Broken Link Preview
By Ugur Saritepe · August 9, 2026
You paste your link into X, LinkedIn, Slack, or iMessage and the preview arrives with no image — just text, or a blank grey box. Almost always it's one of six things, and the raw HTML your server sends tells you which in about a minute. Start there, not in your browser.
The one-minute self-diagnosis
Read the og:image line straight out of your raw HTML — the markup the server returns, before any JavaScript runs:
curl -s https://yourdomain.com | grep -i og:image
What prints tells you which problem family you're in:
- Nothing prints. There's no
og:imagetag the crawlers can see. Go to cause 1. - A line prints. Copy the URL out of
content="…"and open it directly in a browser. Does it load as an image and start withhttps://? Then the tag is fine — look at causes 5–6. Doesn't load, or isn't a fullhttps://address? That's causes 2–4.
One fact sits under all of this: social preview crawlers — facebookexternalhit, Twitterbot, LinkedInBot, Slackbot — fetch the raw HTML and do not run your JavaScript. A tag your React code adds after the page loads is invisible to them. So check the source the server sends, never what devtools shows after the page hydrates.
The same raw-HTML view shows your <title> element. If Google displays a different title than the one you wrote, that is a separate diagnosis: the title tag 60-character limit explains when the cut-off matters.
The six causes, most common first
1. There's no og:image in the raw HTML
Either you never added one, or you added it in client-side code so it only appears after JavaScript runs. Because crawlers don't run JavaScript, a client-rendered tag might as well not exist — and this was the single missing-preview cause in our own scan sample below.
30-second check: the curl … | grep above prints nothing, yet the tag doesappear when you inspect the live DOM in devtools. That gap is the tell: it's being rendered on the client.
og:imagein the raw HTML is the whole problem until you fix it. In Next.js, emit it from the route's metadata (the metadata export or generateMetadata in the App Router) so it ships in the initial HTML — never from a useEffect or a client component. Nothing else on this page matters until the tag is actually in the source.2. The URL is relative, not absolute
og:image has to be a full absolute URL — https://yourdomain.com/og.png, never /og.png. A browser resolves a relative path against the current page, so the image looks right when you visit; a crawler doesn't resolve it, so nothing loads. As of July 2026 Facebook ignores a relative og:imageoutright, and it's a leading cause of blank previews.
30-second check: read the content="…" value from the diagnosis step. It must start with https://. A leading slash or a ./means it's relative.
Fix:emit the absolute URL. In Next.js that's exactly what metadataBase is for — set metadataBase: new URL("https://yourdomain.com") in your root layout and the framework turns your relative image path into a full URL. Current Next.js versions treat a relative og:image with no metadataBase as a build error, so on that stack this usually surfaces before you deploy — but an SPA or a hand-rolled <head> gives you no such warning.
3. The image URL doesn't return a 200 image
The tag is present and absolute, but the URL 404s, redirects, sits behind auth or preview protection, or serves the wrong content type. To a crawler this fails the same way a relative URL does: it asks for the image and gets no image back. Our Triage engine fetches your og:image and flags it unless the URL answers 200 with an image/* content type — the same request the scrapers make.
30-second check:
curl -sI https://yourdomain.com/og.png | grep -i "^HTTP\|content-type"
Good: HTTP/2 200 plus content-type: image/png (or image/jpeg). Bad: a 404, a 3xx redirect, or content-type: text/html — that last one usually means a dynamically generated OG route is returning an error page instead of a picture.
Fix: make the URL answer 200with an image content type. If it's behind a login wall or Vercel preview protection, move the image somewhere public. If it's a generated OG route, confirm it renders a real image in production, not just on your machine — a route that works locally and 404s in production is one of the most common versions of this.
4. It's the wrong format or size
SVG, AVIF, GIF, and WebP are not reliably supported as og:image— Facebook and most platforms skip them. Use PNG or JPEG. Images under 200×200 px are rejected, and files over about 8 MB get dropped. The size that renders everywhere is 1200×630.
30-second check: open the image URL. A .svg, a tiny favicon-sized icon, or a multi-megabyte file will each get skipped.
Fix:serve a 1200×630 PNG or JPEG, kept under about 1 MB so it loads fast and clean.
5. The platform cached an old, imageless preview
You fixed the tag, but the link still previews blank. Facebook, LinkedIn, and the rest cache their first scrape of a URL and don't re-fetch on their own for a long time. You're looking at a stale preview, not a live bug.
30-second check: does the raw HTML now carry a valid, absolute, loading og:image(causes 1–4 all pass) while the preview stays blank? Then it's the cache.
Fix: force a re-scrape. Paste the URL into Facebook's Sharing Debugger and click Scrape Again; use LinkedIn's Post Inspector for LinkedIn. X and Slack usually refresh by themselves within a day or two.
6. Your image is blocked to social crawlers
A robots.txt rule or a firewall that challenges unknown bots will also turn away facebookexternalhit, Twitterbot, and the rest. They're always logged out and identify with their own user-agents; if your protection layer blocks them, they see nothing to preview.
30-second check: fetch the image as a social crawler and read the status:
curl -sI -A "facebookexternalhit/1.1" https://yourdomain.com/og.png | grep -i "^HTTP"
A 200 is good. A 403, a challenge page, or a redirect to a login means the crawler is being blocked. Fix: allow the social preview crawlers through both robots.txt and your firewall. The same misconfiguration often blocks search and AI crawlers too — the Vercel triage guide covers that side.
The verdict: fix exactly one thing this week
Run the checks in order and stop at the first hit:
curl … | grep og:imageprints nothing → add the tag to your server-rendered HTML (cause 1). Nothing else matters until the tag is in the source.- The URL isn't an absolute
https://address → make it absolute (cause 2). - The image URL doesn't answer
200with an image type → fix what it serves (cause 3). Together, causes 2 and 3 — a URL that doesn't load — are the most common way a present tag still shows blank. - It's an SVG / tiny / huge file → serve a 1200×630 PNG or JPEG (cause 4).
- Tag present, absolute, loads, right format — but the preview is still blank → it's cached; re-scrape it (cause 5).
- Still nothing and a firewall or robots rule is in play → let the social crawlers through (cause 6).
How to confirm the fix worked
Re-run the check that caught your cause — the header trace or the grep. Then paste your URL into Facebook's Sharing Debugger: it shows exactly what the crawler sees and re-scrapes on demand. Once the debugger renders your image, every other platform that reads Open Graph will too. If it still shows no image after the tag checks out, you're on cause 5 or 6 — a stale cache or a blocked crawler.
Want the rest of the checks that decide whether you show up at all? The Checks Explained guides cover each one.
Preview tags rot quietly — a renamed image or a moved route breaks them long after you stop looking. If you work in Claude Code or Cursor, the TrafficTriage MCP server hands your assistant a check_pagetool that reads the rendered tags for any URL, so “check the og:image on every page I changed this week” is one message rather than an afternoon.
From experience: the tag is usually there — the image isn't
Of the 23 sites we ran through the Triage engine on July 7–8, 2026, three failed the og:image check. Only one was missing Open Graph tags entirely. The other two had a perfectly valid-looking og:image tag pointing at an image URL that returned a 404— the exact cause 3 trap. In every one of those cases the owner's browser showed the tag sitting right there in the head, so nothing looked wrong until they shared the link.
That's the pattern worth remembering: a blank preview is far more often a tag that points at nothing than a tag that's missing. Reading the head in devtools will never catch it, because the head is fine. Only fetching the image URL the way a crawler does — the curl -sIin cause 3 — tells you the truth. Check what the URL returns, not what the tag says. The same header read catches another silent misconfiguration while you're there: a page that sends Cache-Control: no-store and re-renders on every request.
FAQ
Does og:image have to be an absolute URL?
Yes. It has to be a full https:// URL like https://yourdomain.com/og.png. A relative path such as /og.png renders fine in your browser but social crawlers don't resolve it against your domain, so the image never loads. In Next.js, set metadataBase and the framework composes relative image paths into absolute URLs for you.
I fixed my og:image but the old preview still shows — why?
The platform cached its first scrape of your URL and won't re-fetch on its own for a while. Paste the link into Facebook's Sharing Debugger and click Scrape Again to force a fresh fetch; LinkedIn's Post Inspector does the same for LinkedIn. X and Slack usually refresh by themselves within a day or two.
What size and format should my og:image be?
1200×630 pixels, saved as PNG or JPEG, kept under about 1 MB. Anything below 200×200 is rejected, files over roughly 8 MB get dropped, and SVG, AVIF, GIF, and WebP aren't reliably supported across platforms.
Why does the preview work on one platform but not another?
Each platform scrapes and caches independently, and some read different tags — X checks twitter:image before falling back to og:image. A blank preview on just one platform usually means that platform cached an older scrape (re-scrape it) or you're missing its specific card tag.
Not sure if your link previews are broken?
Get a free Triage Report: eight checks run from your URL alone — including whether your og:image actually loads for crawlers — each scored Critical / Monitor / Healthy, ending with the one thing to fix this week. It renders on your screen in about half a minute — no signup, no email required.
