Fixing X / Twitter Cards
When you post a link on X, formerly Twitter, X fetches the page and builds a card: usually a large image with the site's domain over it, or a small square image beside a short title.
When the card is missing, shows a small image when you wanted a large one, or shows an old image, the cause is almost always one of five things: missing or wrong card tags, the wrong card type, an image X will not use, X's crawler being blocked, or an old card held in X's cache. This guide covers each one, how to tell which you have, and how to fix it.
How X builds a card
When a post containing a link is published, X's crawler requests the page from your server. It identifies
itself with a user agent containing Twitterbot. It reads the HTML head, picks out the card
tags, fetches the image and stores the result. That stored card is what every later post of the same
URL shows, until X fetches the page again.
X looks for information in this order:
- Twitter card tags.
twitter:card,twitter:title,twitter:descriptionandtwitter:image. These are read first. - Open Graph tags. Where a Twitter tag is missing, X falls back to the matching Open
Graph tag:
og:title,og:descriptionandog:image. - No card. Without
twitter:card, or without anything X can use, the link is shown as plain text.
Three things follow from that. X reads the HTML your server sends, not what a browser builds after running JavaScript, so tags added by a script are invisible to it. The image is fetched separately, so a card can fail because of the image alone. And X keeps its copy of the card for about a week, so fixing the page does not change a card X has already stored.
X also changed how cards look. A large-image card now shows the image with the site's domain over it, and in most apps the headline and description are no longer shown under the image. That makes the image the whole card: if the image is wrong, missing or cropped badly, the card fails even when every text tag is perfect.
The card tags X reads
| Tag | What X uses it for | Notes |
|---|---|---|
twitter:card | The card type. | Required. summary_large_image
for a wide image, summary for a small square one. |
twitter:title | The card title where it is shown. | Falls back to og:title.
Keep it under about 70 characters. |
twitter:description | The card description where it is shown. | Falls
back to og:description. Often hidden in the feed. |
twitter:image | The card image. | Falls back to og:image. A full https address. |
twitter:image:alt | Alt text for the image. | Read by screen readers. Describe the image, not the page. |
twitter:site | The X account of the website. | Optional, for example @AiPageSeo. |
twitter:creator | The X account of the author. | Optional. |
A correct set you can copy
<head>
<meta charset="UTF-8">
<title>Winter opening hours and new classes | Riverside Leisure Centre</title>
<link rel="canonical" href="https://example.com/news/winter-timetable">
<meta property="og:type" content="article">
<meta property="og:url" content="https://example.com/news/winter-timetable">
<meta property="og:title" content="Winter timetable: longer opening hours and five new classes">
<meta property="og:description" content="The pool opens at 6am from 1 November, with new spin, yoga and aqua classes every weekday.">
<meta property="og:image" content="https://example.com/images/winter-timetable-1200x630.jpg">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="@RiversideLC">
<meta name="twitter:image:alt" content="The main pool at Riverside Leisure Centre with lane ropes set out">
</head>
This set has no twitter:title, twitter:description or twitter:image,
and does not need them: X uses the Open Graph versions. Add the Twitter versions only if you want X to
show something different. Twitter tags use name=; Open Graph tags use property=.
Choosing the card type
The twitter:card value is the most common cause of a disappointing card, because it decides
the layout regardless of the image you provide.
| Value | What it shows | Use it for |
|---|---|---|
summary_large_image | A wide image across the full width of the post, with the domain over it. | Articles, products, events and almost every page you want people to click. |
summary | A small square image beside the title and domain. | Pages where the image is a logo or icon rather than a picture. |
player | A playable video or audio player. | Media pages. Needs approval from X and extra tags. |
app | An app store card. | App download pages. Needs app store identifiers. |
If twitter:card is missing, X may show no card at all even when every Open Graph tag
is present. If it says summary, a perfect 1200 x 630 image is still shown as a small square.
If your theme or SEO plugin sets it, check its setting: many default to summary.
Images X will show
A card with no image, a small image when you asked for a large one, or a badly cropped image is an image problem.
| Requirement | What works | What fails |
|---|---|---|
| Large card size | 1200 x 628 or 1200 x 630 pixels | Images under 300 x 157 are rejected for a large card. |
| Summary card size | A square of at least 144 x 144 pixels | Wide images are cropped to a square from the centre. |
| File size | Under 5 MB; under 1 MB loads fastest | Larger files are ignored. |
| Format | JPG, PNG, WebP or GIF (first frame only) | SVG is not supported. |
| Address | Full https URL returning 200 | Relative paths, addresses that redirect to a login page. |
| Access | Public, no cookies needed, allowed by robots.txt | Hotlink protection, signed CDN links that expire, image folders blocked for Twitterbot. |
Because the domain is written over the bottom of a large card, keep text and faces away from the lower edge and away from the sides, which are cropped slightly on some screens. The same 1200 x 630 image works for Facebook, LinkedIn, Slack, Discord and WhatsApp.
winter-timetable.jpg?v=2.When X cannot fetch the page
If a link produces no card at all, and the tags are right, X's crawler is probably not getting the page or the image. Check these in order:
- robots.txt. Twitterbot obeys robots.txt. A rule such as
User-agent: * Disallow: /, a rule forTwitterbot, or a rule blocking the image folder stops the card. Allow Twitterbot for the page and the image. - Firewalls and bot protection. Cloudflare Bot Fight Mode, Wordfence, ModSecurity rules and hosting "anti-bot" settings often challenge or block Twitterbot. A challenge page has no tags, so X shows no card. Add an allow rule for the user agent.
- Login walls and cookie gates. A page that sends visitors without a cookie to a login or consent page gives X that page instead.
- Country blocking. Blocking traffic from outside the UK also blocks X's crawler, which does not run from the UK.
- Slow responses and redirects. X gives up on slow pages and on long redirect chains. Share the final address, and keep http-to-https and www redirects to a single hop.
# robots.txt: let Twitterbot read pages and images
User-agent: Twitterbot
Allow: /
Your server's access log settles the question. Post the link, then search the log. No line means the request was blocked before it reached the site; a 403, 429 or 503 means the site refused it; a 200 means the problem is in the tags or the image.
sudo grep -i "twitterbot" /var/log/nginx/access.log | tail -5
Old cards and the X cache
X stores the card it built for each address and reuses it for about seven days. That is why a fixed page can still post with the old image. X no longer offers a public tool to force a fresh card.
- Fix the page and purge any CDN or page cache for that address, so X will be served the new version.
- If you can wait, post the link again after about a week; X will have fetched the page again by then.
- If you need the new card straight away, post the address with a harmless query string, such as
?v=2, which X treats as a new link and fetches fresh. - Check the new card in the X app and on the website, because they crop images slightly differently.
Posts that have already been published keep the card they were created with. Delete and repost, or post the corrected link again, if the old card matters.
The fix, step by step
Step 1
Check what X can see
Run the page through the Social Preview checker, which shows the Twitter and Open Graph tags the way X reads them, together with the card type, image size and image address. Then post the link from a test account, or start a post without publishing it, and note what appears: a large image, a small square image, the domain, or no card at all.
Step 2
Set the card type
View the
page source, not the browser element inspector, and check that twitter:card is in the head
exactly once. Set it to summary_large_image for any page that should show a wide image, and to summary
only for pages whose image is a logo or icon. If your theme or SEO plugin sets it, change the setting
there, because many default to summary.
Step 3
Add the title, description and image
Make sure og:title, og:description and og:image are
present with full https addresses, or add the matching Twitter tags if you want X to show something different.
Add twitter:image:alt describing the picture, and twitter:site with your X
account. Remove duplicate tags added by a second plugin or the theme, because X may pick either copy.
Keep the title under about 70 characters and write the description as a plain summary of the page.
Step 4
Use an image X will show
Open the image address in a private browser window. For a large card it should load straight away as a JPG, PNG or WebP of about 1200 by 628 pixels and under 5 MB. Keep text and faces away from the bottom edge, where X writes the domain. If the image redirects, needs a login or is tiny, replace it and give it a new file name.
Step 5
Let Twitterbot fetch the page
Check
robots.txt first, because Twitterbot obeys it for both the page and the image folder, then the firewall
and any bot protection such as Cloudflare Bot Fight Mode or Wordfence. Post the link and search the server
access log for Twitterbot. No log line means it was blocked before the site; a 403, 429
or 503 means the site refused it.
Step 6
Post a fresh link and check the card
Purge any CDN or page cache for the address so X is served the fixed page. X has no public refresh tool, so either wait about a week for its cached card to expire or post the address with a harmless query string such as ?v=2. Check the new card in the app and on the website before sharing it widely.
Stopping it from coming back
- Tags in the template. Output
twitter:cardset to summary_large_image and a full set of Open Graph tags on every page, from the page's own title, description and featured image. - A default image. Set a site-wide 1200 x 630 fallback image for pages with no featured image, so every card has a picture.
- An allow rule for crawlers. Keep Twitterbot allowed in robots.txt and on the firewall, together with facebookexternalhit, LinkedInBot, Slackbot, Discordbot and WhatsApp.
- New image, new name. Change the file name when you change a share image.
- Check before posting. Run important links through the Social Preview checker before they go out, because a card cannot be refreshed after the post is published.
1. Why is my X (Twitter) card not showing?
Usually because the page has no twitter:card tag, or because X could not fetch the page or the image. Check the page source for twitter:card, then search your access log for Twitterbot right after posting the link. No request means robots.txt, a firewall or bot protection blocked it; a 403 or 503 means your site refused it. If the request succeeded, check that the image address is a full https address that loads without a login.
2. Why does X show a small image instead of a large one?
Because twitter:card is set to summary, or missing, rather than summary_large_image, or because the image is too small for a large card. Set twitter:card to summary_large_image in the page head, or in your theme or SEO plugin settings, and use an image of about 1200 by 628 pixels. X caches cards for about a week, so post the address with a harmless query string such as ?v=2 to see the change straight away.
3. Does X use Open Graph tags?
Yes, as a fallback. X reads its own twitter: tags first and, where one is missing, uses the matching Open Graph tag, so og:title, og:description and og:image are enough for the title, description and image. The one tag X needs that Open Graph does not provide is twitter:card, which sets the card type. Without it X may show no card at all, even when every Open Graph tag is present.
4. How do I refresh an X card?
X no longer offers a public tool to refresh a card, because the Card Validator preview was removed. Fix the page and purge any CDN or page cache, then either wait about a week for X's cached card to expire, or post the address with a harmless query string such as ?v=2, which X treats as a new link. Posts that are already published keep their old card, so repost if the old card matters.
5. Why does my X card show only the domain and no title?
Because that is how X now displays large-image cards. The image fills the card and the site's domain is written over it; in most apps the headline and description are no longer shown under the image. That is not a fault in your tags. It does mean the image has to carry the message, so use a clear, uncluttered picture and keep text and faces away from the bottom edge where the domain appears.
6. What size should an X card image be?
For a summary_large_image card, about 1200 by 628 pixels, a ratio close to 1.91 to 1, saved as a JPG, PNG or WebP under 5 MB and ideally under 1 MB. For a summary card, a square image of at least 144 by 144 pixels. Images smaller than 300 by 157 are rejected for large cards. The same 1200 by 630 image used for Facebook and LinkedIn works well on X too.
7. Does robots.txt affect X cards?
Yes. Twitterbot obeys robots.txt, so a rule that blocks all crawlers, a rule aimed at Twitterbot, or a rule that blocks the folder holding your images will stop the card from appearing. Add a User-agent: Twitterbot section with Allow: / to robots.txt, or make sure your existing rules allow it for both pages and images, then post the address with a harmless query string such as ?v=2 to check the new card.
The Social Preview checker fetches your page the way X, Facebook, LinkedIn, Slack and WhatsApp do, lists every Open Graph and Twitter tag, checks the card type, image size and address, and shows each card side by side.
Open Social Preview Fixes โ