Why your X (Twitter) card still shows the wrong image, even after Open Graph
A page can have perfectly correct Open Graph tags and still show the wrong image when shared on X (formerly Twitter). That's because X's crawler checks for its own twitter:* meta tags first, and only falls back to the og:* tags Facebook and LinkedIn use if the Twitter-specific ones are completely absent. If even one twitter:card tag is present, X treats that as "this page has Twitter tags" and stops looking at Open Graph for the rest — which is how a page ends up with a correct Open Graph image everywhere else, but a stale or missing twitter:image on X alone.
The method
- Decide the card shape first:
summary_large_imagerenders a wide banner above the text;summaryrenders a small square thumbnail beside it. Pick based on the image you actually have — stretching a square logo into a wide banner slot looks worse than just usingsummary. - Add
twitter:cardwith that value. This one tag is what triggers X to stop falling back to Open Graph, so if you add it, add the rest too. - Add
twitter:titleandtwitter:description. These can repeat your Open Graph values, or be written shorter and punchier specifically for the card — they're independent fields. - Add
twitter:imageas a full absolute URL. If this tag is missing buttwitter:cardis present, X does not fall back toog:imagefor the missing piece — it just shows no image, because the fallback is all-or-nothing by tag family, not field by field. - Put all four inside
<head>, and check them with a live card-preview tool after publishing, since a crawler's cached copy of your page can lag behind what you just edited.
A worked example
A page carries both tag families. Its Open Graph image is a 1200×630 banner; its Twitter-specific image is a different, square 600×600 crop meant for the smaller summary layout:
<meta property="og:image" content="https://example.com/banner.png">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="Example Co">
<meta name="twitter:description" content="Short card copy">
<meta name="twitter:image" content="https://example.com/square.png">
Walk the fallback rule on three platforms sharing this exact URL:
- Slack and LinkedIn don't read
twitter:*tags at all, so they useog:image— the 1200×630 banner. - X finds
twitter:cardpresent, stops reading Open Graph for this page entirely, and usestwitter:image— the 600×600 square, rendered small per thesummarycard type. - If the page only had
twitter:cardandtwitter:title— notwitter:image— X would still not borrowog:imageto fill the gap, because the presence oftwitter:cardalready committed it to the Twitter tag family. The result is a card with no image at all, even though a perfectly goodog:imagesits two lines above it in the same<head>.
Where this actually bites
The common failure isn't "forgot the tags" — it's "added twitter:card for the card-type setting and nothing else," usually by copying a snippet from a tutorial that only mentions that one tag. That single tag is enough to switch off the Open Graph fallback without providing anything to replace it. The fix is always the same: if you set twitter:card, set all four tags together, or don't set it and let Open Graph cover X by itself. The Twitter Card tag generator builds the matched set of four so the fallback switch and the tags it disables never ship separately; pair it with the Open Graph generator if you want both platforms covered explicitly rather than relying on a fallback at all.