skip to content

Open Graph and Twitter Cards

The markup that decides what a shared link looks like in Slack, iMessage, or a social feed. Interviewers ask about it in the context of server rendering, because crawlers generally do not run your JavaScript to find these tags.

part ofHTMLoverview, primer and where to startread it →
on this pageshow

questions

5

When someone pastes a link to your page into Slack or a social feed, which Open Graph meta tags decide the preview's title, description and image, and why are Open Graph tags written with property= instead of name=?

level: juniorimportance: must knowfreq 70%

answer

  1. what the scraper reads out of head
  2. four core og:* properties
  3. RDFa vocabulary, not standard metadata name
  4. property= for og:, name= for twitter:

basics

~10 s

Open Graph tags in the head supply the preview: og:title, og:description and og:image, plus og:url and og:type. They use property= because Open Graph is an RDFa vocabulary, unlike Twitter's twitter:* tags, which use name=.

solid answer

~50 s

A link preview is built from `<meta>` tags in the document head. Open Graph defines `og:title`, `og:description` and `og:image` for the visible card, `og:url` as the canonical identity of the thing being shared, and `og:type` (usually `website` or `article`) for what it is. The Open Graph protocol is defined as an RDFa vocabulary, so its tags are keyed by the `property` attribute — `<meta property="og:title" content="...">` — while X's card tags are ordinary named metadata and use `name`, as in `<meta name="twitter:card" content="summary_large_image">`. In practice the big scrapers are forgiving about `name` vs `property` on `og:` keys, but the specification says `property`, so that is what you write. If a page has no Open Graph tags at all, scrapers fall back to guessing from `<title>` and page content, which is how you end up with generic previews.

go deeper

for a junior

Be able to name og:title, og:description, og:image and og:url from memory, say they live in the head, and write them with the property attribute.

for a middle

Explain why Open Graph uses property while twitter:* uses name, and describe how a template should emit these per route rather than once for the whole site.

for a senior

An interviewer expects you to talk about ownership: where in the rendering pipeline the tags are produced, how per-page overrides are enforced, and how a missing or duplicated tag gets caught before it ships.

for a principal

Own the policy question — whether card metadata is a content concern editors control or a platform concern the framework generates, and what you give up either way.

## What a link preview actually is When a URL is pasted into Slack, iMessage, Discord, LinkedIn, Facebook or X, that product sends its own crawler — a "scraper" or "unfurler" — to fetch the URL. The scraper reads the HTML that comes back and looks in the `<head>` for a small set of `<meta>` tags that describe the page as a shareable object. It then renders a card from what it found. Nothing about that card is styled by you: you supply data, the platform supplies the layout. ## The Open Graph protocol Open Graph is the vocabulary almost every platform reads. Its four canonical properties are: - `og:title` — the headline of the card. Not necessarily the same string as `<title>`, which usually carries a site-name suffix for the browser tab. - `og:type` — what kind of object this is. `website` for a generic page, `article` for editorial content; other values exist for video, music and profiles. - `og:image` — an absolute URL to the preview image. - `og:url` — the absolute URL that identifies this object, used by platforms to deduplicate shares of the same page reached through different tracking URLs. `og:description` is not in the required four but is universally supported and is what fills the grey text under the title. `og:site_name` and `og:locale` are optional extras. ```html <head> <meta property="og:type" content="article"> <meta property="og:title" content="How we cut checkout latency in half"> <meta property="og:description" content="A walkthrough of the three changes that mattered."> <meta property="og:image" content="https://example.com/cards/checkout.png"> <meta property="og:url" content="https://example.com/blog/checkout-latency"> </head> ``` ## Why property= and not name= This is the detail interviewers use to check whether you have actually written these tags or only copied them. Ordinary document metadata — `<meta name="description">`, `<meta name="viewport">` — uses the `name` attribute, and `name` is drawn from a registry of standard metadata names. Open Graph is not part of that registry. It is defined as an RDFa vocabulary, and RDFa keys a metadata term with the `property` attribute plus a namespaced value like `og:title`. So the correct spelling is `<meta property="og:title" content="...">`. X's card tags took the other route: `twitter:card`, `twitter:title`, `twitter:image` and friends are plain named metadata and are written with `name`. That is why a real-world head mixes both attributes, and why swapping them on autopilot is a common bug. Most major scrapers today accept `og:` keys under either attribute, so a mistake here often works anyway — which makes it a bug you ship without noticing until one stricter consumer drops your card. ## Per-page, not per-site The single biggest failure mode is treating these tags as site-wide boilerplate. If a template hardcodes one `og:title` and one `og:image` in a shared layout, every URL on the site previews identically, and links stop being clickable in a feed because the card says nothing about the page. Each route should emit its own title, description, image and `og:url`. A sensible default in the layout is fine as long as individual pages override it rather than append to it — two `og:title` tags in one document is ambiguous, and scrapers generally take the first one they encounter. ## What the tags do not do Open Graph tags are not search-ranking signals; they are consumed by link-preview scrapers and social platforms. They are also not a substitute for the page's own visible content: a card that promises something the page does not deliver simply produces bounces. And because they are read out of the HTML the server returns, they have to exist in that HTML — a page that only assembles them later, in the browser, hands the scraper nothing. ## Writing them well Keep `og:title` to roughly a headline's length; platforms truncate. Write `og:description` as a sentence a human would read, not a keyword list. Give `og:image` a real, absolute, publicly reachable URL, and pair it with `og:image:alt` so screen-reader users on the consuming platform get a description of the card art. Set `og:url` to the clean, canonical form of the address so that the same article shared from a newsletter link and from a search result counts as one object.

  • If a page sets both <title> and og:title with different text, which one shows up in a Slack unfurl?
    `og:title` wins — scrapers prefer the Open Graph value when it is present and only fall back to `<title>` when it is absent. That is deliberate: `<title>` is usually written for the browser tab and search snippet and carries a site-name suffix, while `og:title` is written for the card. Keeping them different is normal, not a mistake.
  • Do Open Graph tags help a page rank in search?
    No. They are consumed by link-preview scrapers and social platforms to build cards, not by ranking algorithms. A search engine may use them as a weak hint about a page's content, but the tags that speak to search — the description, canonical and robots directives — are separate. Selling Open Graph as an SEO win in an interview is a red flag.
  • What happens if you emit two og:image tags for the same page?
    Open Graph explicitly allows multiple `og:image` entries as an ordered list of alternatives, and platforms typically take the first one they can fetch and validate — some let the user pick among them. It is legal, but for a predictable card most teams emit exactly one image per page.

saying these in an interview costs you the question

  • Says Open Graph tags improve search rankings
  • Writes og:title with name= instead of property=
  • Puts one hardcoded og:image in the shared layout for every page
  • Assumes the browser tab title is what appears on the card
  • Thinks the platform lets you style the card

context

open as a page

A page declares <meta property="og:image" content="/images/card.png"> and the link preview shows no image on any platform. What is wrong, and which companion og:image properties are worth adding?

level: middleimportance: must knowfreq 62%

basics

~20 s

Open Graph requires absolute URLs, so a root-relative path is unusable by the scraper. Use the full https:// URL, and add og:image:width, og:image:height, og:image:type and og:image:alt so platforms can lay the card out before the file downloads.

open as a page

A single-page app writes each route's Open Graph tags into the document head from JavaScript after the app mounts, yet every shared link still previews with the same site-wide title and image. Why does that happen, and what actually fixes it?

level: seniorimportance: must knowfreq 58%

basics

~20 s

Link-preview scrapers read the HTML the server returns and generally do not execute JavaScript, so they only ever see the shell's fallback tags. The fix is to emit each route's Open Graph tags in the served HTML — server rendering or prerendering — not to inject them later.

open as a page

In X/Twitter card markup, what does <meta name="twitter:card" content="summary_large_image"> change compared with content="summary", and which Open Graph tags does the card fall back to if you omit twitter:title, twitter:description and twitter:image?

level: middleimportance: should knowfreq 50%

basics

~20 s

summary_large_image renders a wide banner card with the image above the text, while summary renders a small square thumbnail beside it. Omitted twitter:title, twitter:description and twitter:image fall back to og:title, og:description and og:image; twitter:card itself has no Open Graph equivalent.

open as a page

You deploy corrected Open Graph tags for an article, but pasting its link into Slack and Facebook still shows the old title and image. What explains that, and how do you get the platforms to pick up the new card?

level: seniorimportance: should knowfreq 42%

basics

~20 s

Platforms cache scraped metadata per URL, so a corrected tag does not take effect until they re-scrape. Force it with the platform's own tool where one exists, such as Facebook's Sharing Debugger, and change the og:image URL when the image itself changed.

open as a page