Twitter Cards vs Open Graph

Two overlapping tag families that mostly do the same job. Here is where they differ, how the fallback works, and the one tag you genuinely have to set.


Twitter Cards and Open Graph are two meta-tag vocabularies that describe the same thing: how a link should look when shared. Open Graph came from Facebook in 2010 and is now read by essentially every platform. Twitter Cards is X's own namespace, layered on top. The important detail is that they are not competing standards — X falls back to og: tags for anything it cannot find in twitter:. So the practical question is not which to use, but how few twitter: tags you can get away with. The answer is one.

How the Fallback Works

When X scrapes a page it looks for each value in a specific order and takes the first it finds:

text
Headline: twitter:title -> og:title -> <title> Description: twitter:description -> og:description -> meta description Image: twitter:image -> og:image -> (none) Alt text: twitter:image:alt -> og:image:alt -> (none) Layout: twitter:card -> (no fallback — defaults to "summary")

Every row falls back cleanly except the last. twitter:card has no og: equivalent, so if you omit it X assumes summary — the small layout. That single tag is the entire practical difference between a page that shares well on X and one that does not.

One tag is the whole answerIf you already have complete Open Graph tags, adding <meta name="twitter:card" content="summary_large_image"> is the only change X needs. Everything else duplicates values it would have taken from og: anyway.

summary vs summary_large_image

The two card types you will actually use, and the visual difference is substantial:

text
summary (the default when twitter:card is absent) +--------+---------------------------------+ | [img] | How We Cut Build Times by 70% | | 120px | A walkthrough of the caching... | | square | example.com | +--------+---------------------------------+ summary_large_image +--------------------------------------------+ | | | full-width 1.91:1 image | | | +--------------------------------------------+ | How We Cut Build Times by 70% | | A walkthrough of the caching changes... | | example.com | +--------------------------------------------+
Card typeImageUse for
summarySmall square thumbnail, minimum 144 × 144Text-led content where the image is incidental
summary_large_imageFull-width, 1.91:1, minimum 300 × 157Almost everything — articles, products, landing pages
playerEmbedded video or audio playerMedia sites; requires approval from X
appApp store cardMobile app install links

player and app are specialised and rarely relevant. For ordinary web content, summary_large_image is the right answer essentially every time.

Where the Two Actually Differ

Open GraphTwitter Cards
Attributeproperty=name=
Prefixog:twitter:
Read byFacebook, LinkedIn, Slack, Discord, WhatsApp, iMessage, XX only
Controls layoutNoYes, via twitter:card
Image ratio1.91:12:1 for summary_large_image
Attribution tagsVia og:site_nametwitter:site, twitter:creator (@handles)
Multiple imagesAllowedOne only

The two genuine capabilities Twitter Cards add are the layout switch and the @handle attribution. Everything else is duplication.

The Aspect Ratio Difference

Open Graph standardised on 1.91:1 (1200 × 630); X displays summary_large_image at 2:1. Feed a 1200 × 630 image to X and it crops roughly 15 pixels off the top and bottom.

That is a small enough difference that a single 1200 × 630 image is fine for both, provided you keep logos and text away from the vertical edges. If your design has content close to the top or bottom, a dedicated 1200 × 600 image for X avoids it:

html
<meta property="og:image" content="https://example.com/og/article-1200x630.png"> <meta name="twitter:card" content="summary_large_image"> <meta name="twitter:image" content="https://example.com/og/article-1200x600.png">

For most sites this is not worth the extra asset. See the og:image Size Guide for the safe-zone geometry.

twitter:site and twitter:creator

The two tags with no Open Graph equivalent worth setting. They attribute the card to X accounts:

html
<meta name="twitter:site" content="@example"> <!-- the publisher's account --> <meta name="twitter:creator" content="@janedev"> <!-- the author's account -->

Both take an @handle including the @. Their visible effect on the card is minor and has changed over time, but they cost nothing and are the correct way to express authorship on X.

What to Actually Publish

For the overwhelming majority of sites, this is the complete answer — full Open Graph plus one twitter: tag:

html
<meta property="og:title" content="How We Cut Build Times by 70%"> <meta property="og:description" content="A walkthrough of the caching changes that took our CI from 14 minutes to 4."> <meta property="og:image" content="https://example.com/og/build-times.png"> <meta property="og:image:width" content="1200"> <meta property="og:image:height" content="630"> <meta property="og:url" content="https://example.com/blog/build-times"> <meta property="og:type" content="article"> <meta property="og:site_name" content="Example"> <meta name="twitter:card" content="summary_large_image"> <meta name="twitter:site" content="@example">

Add twitter:title, twitter:description or twitter:image only when you deliberately want X to show something different from every other platform — a shorter headline, a different crop, a tone that suits the audience there.

Do not duplicate for the sake of itMirroring every og: tag into a twitter: equivalent doubles your markup and doubles the number of places a value can go stale. A page where og:title was updated and twitter:title was not will show two different headlines depending on where it is shared.

Verifying What X Will Use

X's standalone Card Validator has been retired, so verification is now done by checking the served markup and observing a real post:

bash
# Every tag from both namespaces, as a scraper sees them curl -sL https://example.com/page | grep -iE '<meta[^>]+(og:|twitter:)' # Is the layout tag present at all? curl -sL https://example.com/page | grep -i 'twitter:card' # Which image will X use? twitter:image wins if present, else og:image curl -sL https://example.com/page | grep -iE 'twitter:image|og:image"'

The Open Graph Checker resolves the fallback chain for you and shows which value each platform ends up with, including X.

Frequently Asked Questions

Do I need Twitter Card tags if I already have Open Graph?

Only twitter:card. X falls back to your og: tags for the title, description and image, so the rest of the namespace is redundant unless you deliberately want different content on X.

What happens if I omit twitter:card?

X defaults to summary — a small square thumbnail beside the text rather than the full-width image card. Your tags are being read correctly; the layout is just the compact one.

Which wins if both twitter:image and og:image are set?

twitter:image wins on X. Every other platform ignores it and uses og:image. That is exactly the mechanism to use if you want a different crop or image on X specifically.

Do twitter: tags work on other platforms?

No. LinkedIn, Facebook, Slack and the rest read only og:. A page with twitter: tags and no Open Graph will share well on X and badly everywhere else, which is the reverse of the mistake most people worry about.

Is there still a Twitter Card Validator?

Not as a standalone tool — it was retired. Verify by inspecting the served HTML with curl or a checker, then confirm with a real post. Cards on X also refresh more readily than Facebook's, so a corrected tag usually appears on the next share.

What image size should I use for X?

A 1200 × 630 Open Graph image works fine — X crops it slightly to reach 2:1. If your design has content near the top or bottom edge, supply a 1200 × 600 image via twitter:image instead.

Related