The tags platforms actually read
Link previews are generated from Open Graph tags in the page head — og:title, og:description, og:image, og:url and og:type. Originally a Facebook specification, it is now read by LinkedIn, WhatsApp, Slack, Discord, Signal, iMessage and most other platforms.
Twitter reads its own twitter: tags but falls back to Open Graph where they are missing, so an Open Graph set alone covers essentially everything. The one tag worth adding separately is twitter:card, which chooses between a large image and a compact side-by-side layout.
Images must be referenced by absolute URL — a relative path fails, because the platform's crawler has no page context. The image must also be publicly reachable without authentication, which is the usual reason previews work in development and fail in production behind access control, or the reverse.
Sizes, cropping and legibility
1200 × 630 is the practical standard, giving the 1.91:1 ratio most platforms expect. Platforms crop rather than letterbox, so anything important must sit within a safe central area — a design that fills the full frame will lose its edges somewhere.
Text in the image needs to be far larger than feels necessary. Previews render small, often 400 pixels wide or less in a feed and smaller still in a chat client, so a headline at what looks like a comfortable size in the design file is unreadable at delivery. Reduce the finished image to 400 pixels wide and check it there — if the text does not read, it is too small.
Keep the file under about 1 MB; some platforms reject or skip larger images. JPEG suits photographic cards and PNG suits flat graphics with text, where JPEG's artefacts around sharp edges are most visible.
Caching, and why the old image keeps appearing
Every platform caches previews aggressively, and this is the single most common frustration. Once a URL has been shared, its preview may persist for days regardless of what you change on the page, because the crawler does not revisit on every share.
Each platform provides its own tool to force a refresh — Facebook's Sharing Debugger, LinkedIn's Post Inspector, Twitter's card validator. Running the URL through those after publishing updates the cache immediately, and is worth doing as a routine step rather than after discovering a problem.
The workaround where a cache will not clear is a changed URL, since a different query string is a different resource as far as the crawler is concerned. It is also worth checking that your image URL is not itself cached at a CDN with a long lifetime, and that the crawler is not being blocked — robots.txt rules and bot-protection services both routinely block preview crawlers, which produces a card with a title and no image.