You paste your link into a chat and get a bare blue URL where a card should be. Nothing on the page is wrong — it renders fine in a browser — but the preview is empty, or it is a tiny square thumbnail, or it shows a headline from six months ago. Almost every case is one of a small number of causes, and they are all visible from outside the page.
A preview is a separate visit by a different program
When you share a link, the platform sends its own crawler to fetch that page — facebookexternalhit for Facebook and WhatsApp, Twitterbot for X, Slackbot for Slack. That crawler is not your browser. It downloads the HTML, reads a handful of <meta> tags out of the <head>, and leaves. It does not log in, it does not wait for anything, and in general it does not run your JavaScript.
Three consequences follow from that, and they explain most empty cards. A page that builds its meta tags on the client has no tags as far as the crawler is concerned. A page behind a login or a country block returns the login page's tags, not the article's. And a crawler fetching your image from its own servers cannot resolve a relative URL, because there is no page for it to be relative to.
The four tags that decide what the card looks like
og:title is the headline. Without it platforms fall back to your <title>, which is written for a search result and usually reads badly as a headline — most platforms cut the card headline around 88 characters, so front-load the words that matter.
og:description is the line or two underneath. Cards show roughly 200 characters and some clients cut nearer 125 on a phone; the rest is dropped rather than wrapped. og:url is the canonical address shares get attributed to, so the same page reached through different query strings counts as one page rather than several.
og:image is the one that actually fails. It must be an absolute https:// URL, it wants to be 1200x630, and the file has to be reachable by a stranger — an image behind hotlink protection or an authenticated CDN will 403 for the crawler and render no card at all.
- Declare
og:image:widthandog:image:height. Some scrapers will not commit to a large preview until they have downloaded and measured the file, and show a small thumbnail on the first scrape instead. - Set
og:image:typetoimage/pngorimage/jpeg. Thefacebookexternalhitstack, which WhatsApp shares, reads the declared MIME type. - If you set
og:image:secure_url, make it absolute. A relative one is worse than omitting the tag, because a scraper may prefer it and then fail to load anything. - Add
twitter:cardwith the valuesummary_large_image, or X falls back to a small square thumbnail even when your image is the right shape.
Why it works on Slack but not on WhatsApp
Each platform reads a slightly different subset of the tags and falls back differently when one is missing. Slack is forgiving and will assemble a card out of <title> and the meta description alone. X needs twitter:card to be told it wants the wide layout. The Facebook and WhatsApp crawler is the strictest about absolute URLs and declared image types, which is why WhatsApp is so often the one platform that shows nothing.
So a card that works in one place and not another is normal, and it is not a sign that the platform is broken. It means you are relying on a fallback that the strict crawler does not implement.
Platform by platform: the usual culprit
Each platform has a failure it's known for. If the card is missing on one platform only, start with the check listed for it.
- WhatsApp link preview not showing: check that
og:imageis an absolutehttps://URL and that the file is small. Large images are often skipped, so keep it well under a megabyte. A small square thumbnail instead of a wide card usually meansog:image:widthandog:image:heightare missing. - Facebook: a card with no image nearly always means the image returned an error to the crawler. Facebook's Sharing Debugger shows exactly what it fetched and has a Scrape Again button, which also clears the cached card WhatsApp uses.
- LinkedIn preview not updating: LinkedIn keeps the first card it scraped for a URL. Run the URL through its Post Inspector to fetch it again. If the old image still appears, publish the new image under a new file name.
- X (Twitter): a small square card when you expected a large one means
twitter:cardis missing or set tosummary. Set it tosummary_large_image. - Slack and Discord: both build a card from
<title>and the meta description when Open Graph tags are missing, so a working card there does not prove your tags are right. - iMessage: the preview is built on the sender's phone rather than by a crawler, so it can differ from every other platform and reflects what that device could load at the moment of sending.
Fixed it and the old card is still showing
This is the last common cause, and it is not a bug in your page. Every platform caches what it scraped, often for days, and correcting the tag does not invalidate that cache. Until it expires or you force a re-scrape, everyone who shares the link keeps seeing the old headline and the old image.
Each platform has its own way to clear it — Facebook's Sharing Debugger, X's Card Validator, LinkedIn's Post Inspector. A useful trick while you are still iterating is to append a throwaway query string to the URL you test with, since that is a different cache key.
In short
Check the page from outside itself, because that is the only place the failure is visible. Paste the URL into the Open Graph checker: it fetches the page the way a platform would, tells you which tags are present, which are missing, and whether the image URL a stranger requests actually returns an image.
Open Graph Checker
See how a link will look when shared, and what's stopping the preview image from showing.
Keep reading
UUID v4 vs v7: which one belongs in your database?
Random UUIDs scatter writes across an index. Time-ordered v7 fixes that, at the cost of revealing creation time — how to choose between them.
What makes a password strong (it isn't the symbols)
Why length beats complexity, what entropy in bits actually measures, and why the old advice about special characters made passwords worse.
MD5, SHA-1, SHA-256: which hash should you actually use?
What it means for a hash to be broken, why fast hashes are the wrong tool for passwords, and how to verify a downloaded file properly.