There is no such thing as one share preview
Most checkers show a single card and label it "preview". No platform renders that card. X reads twitter:title before og:title; LinkedIn ignores the twitter: namespace entirely, so a page whose only image is a twitter:image posts to LinkedIn with no image at all. Slack reads og: first and falls back to twitter:. Discord takes the coloured bar down the side of its embed from theme-color, which nothing else uses.
So this resolves each platform separately and tells you which tag won. "Your title came from <title>, not og:title" is the answer to most of the questions people arrive here with, and a merged preview cannot express it.
The two tools that used to answer this are gone
X retired its Card Validator in 2023, and there is no replacement: the only way to see an X card now is to post the link. Facebook's Sharing Debugger still exists but sits behind a logged-in developer account, which is a strange requirement for reading tags that are public by definition. LinkedIn's Post Inspector still works and is still the right tool for one specific job, forcing a cache refresh, which nothing else can do for you.
Nothing here fetches your page from your browser. The tags are read server-side and parsed locally, and if you paste HTML instead, the page never leaves your machine.
The failure is almost always the image
A relative og:image. This is the single most common broken card. content="/img/hero.png" works when you click it in your editor, because your browser resolves it against the page. Crawlers do not. The tag has to carry the whole absolute URL, scheme and domain included.
No twitter:card. The full-width image on X and Discord is opt-in. With an image but no twitter:card set to summary_large_image, you get the small square thumbnail beside the text, and people usually conclude the image is broken when it is only small.
Missing og:image:width and og:image:height. Without them a platform has to download the image before it knows its shape, so the very first time a URL is shared the card often renders blank and only looks right afterwards. Declaring 1200 and 630 removes that first-share gap.
Tags added by JavaScript. Crawlers read the HTML that arrives over the wire. A tag injected after load exists for a browser and does not exist for a crawler, which is also why tags that end up in the <body> are ignored.
Every platform caches, and they disagree about that too
Fixing a tag does not fix a link you already posted. LinkedIn holds a card for around seven days and its Post Inspector is the only way to force a refresh. Telegram caches per URL and only @WebpageBot clears it. Facebook re-scrapes when you run the URL through its debugger. iMessage has no central cache at all, because it fetches from the device, so a corrected tag shows up on the very next send. Adding a harmless query parameter to the end of a URL is the general-purpose escape hatch: to a cache it is a new URL.