SiteAssets SiteAssets
Blog · Platforms 6 min read

Twitter Card not showing? Run through these seven checks

A card that refuses to appear is almost always one of seven causes. They are cheap to rule out, and the order below moves from the most common to the most obscure.

6 min read SiteAssets team

X removed its public Card Validator, which turned a five-second diagnosis into guesswork. The checks below replace it: each one is observable from the command line or from the post composer, without publishing anything.

One: the card type is missing or wrong

Without twitter:card, X guesses. It usually guesses wrong for wide images. Declare the type explicitly — summary_large_image for a 1.91:1 image, summary for a square thumbnail next to the text.

html
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="A specific, readable title" />
<meta name="twitter:description" content="One sentence that earns the click." />
<meta name="twitter:image" content="https://example.com/og/1200x628.png" />

Two: the image is below the minimum or above the limit

summary_large_image needs at least 300 × 157; summary needs at least 144 × 144. Both accept files up to 5 MB. An image that is 299 pixels wide fails silently, which is why favicons and thumbnails reused as cards are the most common cause of a text-only post.

Three: the image URL is relative

X does not resolve relative paths at unfurl time. content="/og.png" produces no image. The same applies to og:image. Always include the scheme and host, even when the rest of your head uses relative URLs.

Four: Xbot is blocked

Check robots.txt for a rule that accidentally catches Twitterbot. A CDN or WAF challenge is just as fatal — X does not solve CAPTCHAs. Verify with the user agent X actually sends:

bash
curl -A "Twitterbot/1.0" -I https://example.com/article
# Expect: HTTP/2 200, content-type: text/html
# A 403, 429 or a JavaScript challenge page means the card will never render.

Five: the tags are rendered client-side

The crawler does not run your JavaScript bundle. Tags injected by useEffect, onMounted or a client-side head library are invisible to it. View source — not inspect element — and confirm the meta tags are in the raw HTML response.

Six: the URL redirects

X follows a small number of redirects, but cross-domain redirects frequently lose the tags. A link shortener in front of the canonical URL, or an http to https redirect that lands on a page without tags, both break the card. Share the final URL directly when testing.

Seven: you are testing with a URL X will not unfurl

Localhost, private IPs, tunnel URLs that require a header, and pages behind authentication never produce cards. Neither do links to files without an HTML content type. Test with the real public page.

Why the card appears, then disappears

X caches a card once per URL, keyed on the exact string. If you edit the page after the first unfurl, the old card persists. Adding a query string forces a fresh entry for testing, but the cleanest fix is a new image filename plus a re-scrape through the composer.

One more quirk: if a page declares both twitter:image and og:image with different files, X uses twitter:image. If only og:image exists, X falls back to it — but the fallback is less reliable during high load, which is why explicit tags are worth the four lines.

Try it on your own site

Fifteen checks, about five seconds.

Paste a deployed URL and read the check table: weight, status and the rule behind every row.