Validates Twitter Card meta tags for social media sharing optimization
3 of 3 free audits left today
See what Twitter Card finds on your site. No sign-up needed.
Fetch β requests the HTML through the core HTTP fetcher (including HTTP Basic Auth when provided). A blocked request (HTTP 403, 429 or a Cloudflare challenge) ends with 37A-TwitterCardAuditor-590; any other fetch failure produces an ERROR response with 37A-TwitterCardAuditor-500.
Collect β reads every <meta> whose name (or property) starts with twitter:, keeping document order and repeated values.
Probe β when twitter:image is an absolute URL, sends one HEAD request (falling back to GET on 405) and records the HTTP status and Content-Type; both image rules read that single answer.
Rules β a missing or blank twitter:card or twitter:title is a FAIL. Empty optional tags, duplicated tags, unknown twitter: tags, an unsupported card type, relative or off-host URLs, card types without the tags they need, an image without alt text, and an unreachable or non-image twitter:image are WARNINGs.
Aggregate β ERROR wins, then FAIL, then WARNING; if every rule passes, the audit is SUCCESS.
Specification pin β every run emits 37A-TwitterCardAuditor-100 (INFORMATION) naming the X Cards markup reference. That check does not change overall status.
Every row maps to one checkRule* method and one CheckCode. 37A-TwitterCardAuditor-100 is emitted on every run, including fetch errors. Image rules 312 and 313 only run when twitter:image is absolute, and 313 is skipped when 312 fires. Card type comparisons ignore case. CheckCode suffixes use status ranges: 100 information, 200 success, 300β399 warning, 400β499 fail, 500β599 error.
| CheckCode | Status | When it fires | Recommendation | Why it matters |
|---|---|---|---|---|
37A-TwitterCardAuditor-100 | INFORMATION | Every run. Records that this auditor implements the X (Twitter) Cards markup reference published at https://developer.x.com/en/docs/x-for-websites/cards/overview/markup. | β (recommendation is null; nothing for the site to change) | β |
37A-TwitterCardAuditor-400 | FAIL | A required tag (twitter:card or twitter:title) is absent from the page. One check per tag. | Add <meta name="{tag}" content="{example}"> to the <head> of {url}. | Without twitter:card and twitter:title X has no card to render, so links shared from the page appear as bare URLs and get far fewer clicks. |
37A-TwitterCardAuditor-401 | FAIL | A required tag is present but every value is blank. One check per tag. | Fill the content attribute of {tag} on {url}, for example <meta name="{tag}" content="{example}">. | An empty card type or title gives X nothing to render, so the shared link shows no preview and the empty tag hides the problem from whoever maintains the page. |
37A-TwitterCardAuditor-300 | WARNING | An optional (non-required) twitter: tag has a blank value. One check per tag. | Fill the content attribute of {tag} on {url} or remove the tag. | X takes an empty value as the final answer instead of falling back to the page or the Open Graph tags, so the card loses that detail and the shared link gets fewer clicks. |
37A-TwitterCardAuditor-301 | WARNING | A twitter: tag is declared more than once; the message lists the values. One check per tag. | Keep a single {tag} on {url} ("{firstValue}") and remove the other {count - 1}. | When a tag is repeated, X picks one value and other tools pick another, so the card may show a title, image or description you did not intend. |
37A-TwitterCardAuditor-302 | WARNING | A twitter: tag is neither required nor one of the optional tags the markup reference defines. One check per tag. | Remove {tag} from {url} or rename it to a documented tag such as twitter:description, twitter:image or twitter:site. | X ignores tags it does not know, so the detail the tag was meant to add never reaches the card and the page carries dead markup that hides a typo in a tag that does matter. |
37A-TwitterCardAuditor-303 | WARNING | twitter:card is not summary, summary_large_image, app or player. | Set twitter:card on {url} to summary, summary_large_image, app or player instead of "{cardType}". | X only renders the card types it defines; with an unknown type the shared link shows no preview at all and draws far fewer clicks. |
37A-TwitterCardAuditor-304 | WARNING | twitter:image is present but not an absolute URL. | Set twitter:image on {url} to an absolute https URL, for example "{resolved}". | X does not resolve a relative image path, so the card renders without a picture and the shared link stands out far less in the feed. |
37A-TwitterCardAuditor-305 | WARNING | twitter:url is present but not an absolute URL. | Set twitter:url on {url} to the canonical absolute URL, for example "{resolved}". | A relative twitter:url cannot be attributed to a page, so the card may link to the wrong address or be dropped, and engagement is split across several URLs. |
37A-TwitterCardAuditor-306 | WARNING | twitter:url is absolute and its host differs from the audited page host (skipped when 305 applies). | Point twitter:url on {url} at the canonical URL on {pageHost} instead of "{twitterUrl}", or audit {twitterUrlHost} instead. | X attributes the card to the twitter:url host, so engagement is credited to another site and the card can send visitors away from your page. |
37A-TwitterCardAuditor-307 | WARNING | twitter:card is summary_large_image but twitter:image is absent or blank. | Add <meta name="twitter:image" content="https://β¦"> pointing at a 2:1 image of at least 300Γ157 pixels to {url}, or change twitter:card from "{cardType}" to "summary". | A large-image card exists to show a picture; without one X falls back to a plain summary, so the shared link loses the visual space it asked for and draws fewer clicks. |
37A-TwitterCardAuditor-308 | WARNING | twitter:card is player but twitter:player is absent or blank. | Add <meta name="twitter:player" content="https://β¦"> with the HTTPS URL of the player iframe to {url}, or change twitter:card from "{cardType}" to "summary". | A player card without a player URL cannot embed the media, so X shows no card and people cannot watch or listen from the timeline. |
37A-TwitterCardAuditor-309 | WARNING | twitter:card is player but twitter:player:width or twitter:player:height is absent or blank; the message names the missing one(s). | Add {missingTags} to {url} with the player size in pixels, for example <meta name="twitter:player:width" content="480"> and <meta name="twitter:player:height" content="270">. | X needs the player dimensions to reserve space for the embed; without them the card is rejected and the media never plays inline. |
37A-TwitterCardAuditor-310 | WARNING | twitter:card is app but none of twitter:app:name:iphone, twitter:app:name:ipad or twitter:app:name:googleplay has a value. | Add at least one app platform to {url}, for example <meta name="twitter:app:name:iphone" content="β¦"> with its twitter:app:id:iphone, or change twitter:card from "{cardType}" to "summary". | An app card without an iPhone, iPad or Google Play app name has nothing to promote, so X shows no install button and the card brings no downloads. |
37A-TwitterCardAuditor-311 | WARNING | twitter:image has a value but twitter:image:alt is absent or blank. | Add <meta name="twitter:image:alt" content="β¦"> describing "{image}" in up to 420 characters to {url}. | Without alt text, screen reader users hear nothing about the card image, so part of the audience misses the message and the page falls short of accessibility expectations. |
37A-TwitterCardAuditor-312 | WARNING | The absolute twitter:image answered a non-2xx status or the request failed; the check resource is the image URL. | Make "{image}" answer HTTP 200 with a public image (last answer: {HTTP status or error}), or point twitter:image on {url} at a reachable URL. | When the image cannot be fetched, the card renders without a picture, and shared links without a preview image are clicked far less. |
37A-TwitterCardAuditor-313 | WARNING | The reachable twitter:image is not served as image/jpeg, image/jpg, image/png, image/gif or image/webp (skipped when 312 applies); the check resource is the image URL. | Serve "{image}" as image/jpeg, image/png, image/gif or image/webp instead of "{contentType or missing}". | X ignores an image it cannot decode, so the card renders without a picture and the shared link draws fewer clicks. |
37A-TwitterCardAuditor-500 | ERROR | The page could not be fetched (network error, timeout, HTTP 404, HTTP 5xx). | Make {url} reachable over HTTP(S) and re-run the audit. Last error was "{error}". | β |
37A-TwitterCardAuditor-200 | SUCCESS | Every rule above passed. Message is Twitter Card "{cardType}" with title "{title}" is valid on {url}; {foundCount} twitter: tag(s) found, twitter:image served as {contentType}. | β | β |
37A-TwitterCardAuditor-590 | ERROR | The audited page answered HTTP 403, HTTP 429 or a Cloudflare challenge, so 37AuditsBot was blocked before it could read the page. | Allow 37AuditsBot in your firewall or bot protection: allowlist its user agent, or verify its Web Bot Auth signature. See https://www.37audits.com/bot. | While 37AuditsBot is blocked this audit cannot look at the site, so problems on it go unreported. |
| Status | Description | Test logic |
|---|---|---|
| SUCCESS | twitter:card and twitter:title are present, the card type and its dependent tags are consistent, twitter:url and twitter:image are absolute and on the page host, and the image is reachable as a supported type | Both required tags have a non-blank value and no warning rule fires (200). |
| WARNING | A card will render, but some tags are weak or inconsistent | Empty optional tag (300); duplicated tag (301); unknown twitter: tag (302); unsupported card type (303); relative twitter:image (304); relative twitter:url (305); twitter:url on another host (306); summary_large_image without image (307); player without player (308) or dimensions (309); app without platform (310); image without alt (311); image unreachable (312); image not an image type (313). |
| FAIL | A required tag is missing or empty, so X has no card to render | twitter:card or twitter:title absent (400) or present with blank content (401). |
| ERROR | The auditor could not read the page | Page fetch failed (500); 37AuditsBot was blocked (590). |
| INFORMATION | Specification pin | Always emitted (100); does not change overall status. |
twitter:card selects the layout and twitter:title is the headline; without either, X shows a bare link. X falls back to og:title, og:description and og:image for the other fields, but not for the card type.
A required tag with an empty content is as bad as a missing one and is harder to spot in a template, so it fails rather than warns.
Only summary, summary_large_image, app and player render; photo, gallery and product cards were retired and now produce no preview.
A summary_large_image card needs twitter:image; a player card needs twitter:player with twitter:player:width and twitter:player:height; an app card needs at least one twitter:app:name:* platform.
Comparisons of the card type ignore case, so Summary passes 303 but is still worth normalising.
twitter:url is not part of the current markup reference but is widely used; when present it should be the canonical absolute URL on the page host, otherwise the card is attributed to another address.
twitter:image must be an absolute, publicly fetchable URL served as JPEG, PNG, GIF or WebP (SVG is not rendered). A 403, 404 or timeout leaves the card without a picture.
The auditor probes with HEAD first and retries with GET on 405; servers that reject HEAD with other status codes will warn under 312.
twitter:image:alt (up to 420 characters) is read by screen readers; it is a warning, not a failure, because the card still renders without it.
X uses the first occurrence of a repeated tag; repeating twitter:title or twitter:image is ambiguous and usually a template leftover.
An optional tag with an empty content is treated as the final value, so it should be filled or removed.
Known tags are the ones listed in the markup reference plus twitter:url, twitter:domain, twitter:player:stream:content_type and twitter:app:country; any other twitter: tag warns so a typo in a tag that matters (for example twitter:imag) is caught.
This documentation is built and hosted on Mintlify, a developer documentation platform.
Add this auditor to your monitoring setup and start identifying issues on your websites today.