The URL gets shared. A blank card appears. No image, the wrong title, no description. The link works. It just looks like nothing.
That blank card is not a design problem. It is a missing configuration. OpenGraph is the layer that controls what every platform renders when a URL is shared. Without it, platforms guess. Twitter scrapes the page title. LinkedIn hunts for the first image it can find. Chat apps show nothing at all. Every share becomes a missed first impression, and the person who shared it sees the gap before anyone else does.
It lives in the gap a build never catches. No test fails when it is absent. The page looks correct in the browser. The problem only surfaces somewhere else, after the link has already left your hands.
How it works
OpenGraph is a set of meta tags that live in the document head, invisible to anyone browsing the page. The browser ignores them entirely. What reads them is a different kind of visitor — a crawler sent by each social platform the moment a URL is pasted anywhere. It arrives, reads the tags, assembles a preview card from what it finds, and leaves. The card the reader sees on the other end is built entirely from those tags.
The tags must be in the HTML the crawler receives. If the page builds them with JavaScript after load, the crawler is already gone by then. It reads raw HTML, sees nothing, and the card comes up blank — while the browser, where everything runs, shows the page perfectly.
A complete implementation
This is what a fully specified page head looks like. Every section below breaks down what each tag does and what breaks when it is missing.
<!-- Core OpenGraph -->
<meta property="og:title" content="Page Title Here" />
<meta property="og:description" content="Short summary of the page." />
<meta property="og:url" content="https://www.example.com/page/" />
<meta property="og:type" content="website" />
<meta property="og:site_name" content="Site Name" />
<meta property="og:locale" content="en_US" />
<!-- Image -->
<meta property="og:image" content="https://www.example.com/card.png" />
<meta property="og:image:secure_url" content="https://www.example.com/card.png" />
<meta property="og:image:type" content="image/png" />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
<meta property="og:image:alt" content="Description of the image for screen readers." />
<!-- Twitter / X -->
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:site" content="@sitehandle" />
<meta name="twitter:creator" content="@authorhandle" />
<meta name="twitter:title" content="Page Title Here" />
<meta name="twitter:description" content="Short summary of the page." />
<meta name="twitter:image" content="https://www.example.com/card.png" />
<meta name="twitter:image:alt" content="Description of the image." />Core tags
These go on every page. Without any one of them, the preview card degrades or breaks on most platforms.
og:title
The headline that appears on the share card. Platforms fall back to the <title> tag when this is absent, which is often padded with the site name or cut at an awkward length. Keep it under 60 characters — longer titles are truncated, and the cutoff varies by platform.
<meta property="og:title" content="How to Fix Core Web Vitals" />og:description
The text shown below the title. Not used for search ranking — purely for the share card. Some platforms show it, some truncate it, some skip it entirely. Keep it under 155 characters. Without it, platforms either scrape random body text or show nothing.
<meta property="og:description" content="LCP, CLS, INP — what they measure, where to find them, and how to fix each one." />og:url
The canonical URL of the page. Tells platforms which URL to use when caching and deduplicating shares. Without it, a page shared under multiple URLs — with and without trailing slash, with query parameters, from different environments — can accumulate separate cache entries that show different previews for what is effectively the same page.
<meta property="og:url" content="https://www.example.com/article/" />og:type
Declares what kind of content the page contains. Controls how some platforms structure the card. website is the generic default. article enables article-specific sub-tags. Other valid values are listed in the type-specific sections below.
<meta property="og:type" content="website" />
<!-- or -->
<meta property="og:type" content="article" />Valid og:type values: website, article, book, profile, music.song, music.album, music.playlist, music.radio_station, video.movie, video.episode, video.tv_show, video.other.
og:site_name
The name of the site, separate from the page title. Some platforms show it above the card headline — a label that tells the reader where the link leads before they even read what it says. The page title changes with every article; the site name stays constant and carries the brand.
<meta property="og:site_name" content="Nitish Kumar" />og:locale
The language and territory of the page content. Format is language_TERRITORY — en_US for American English, en_GB for British English, hi_IN for Hindi. Defaults to en_US when absent. Used by platforms to serve the correct language version of a card when multiple locale variants exist.
<meta property="og:locale" content="en_US" />og:locale:alternate
Declares alternative language versions of the same page. One tag per locale. Only relevant for multilingual sites that serve the same content in different languages at different URLs.
<meta property="og:locale" content="en_US" />
<meta property="og:locale:alternate" content="fr_FR" />
<meta property="og:locale:alternate" content="de_DE" />og:determiner
The word that appears before the title in a sentence — used in phrases like "a page", "an article", "the song". Valid values: a, an, the, auto, or an empty string. auto lets the platform choose based on the title. Rarely surfaces in rendered cards but is part of the full OGP spec.
<meta property="og:determiner" content="the" />Image tags
The image is the part of the card with the most rules. Each sub-tag adds information that helps platforms serve the image correctly without having to fetch and analyse it first.
og:image
The preview image URL. Must be absolute — https://www.example.com/card.png works, /card.png does not. Without this, most platforms render a text-only card or nothing at all. One og:image tag per image — multiple images require multiple sets of image tags in sequence.
<meta property="og:image" content="https://www.example.com/card.png" />The spec also defines og:image:url as a structured alias — identical to og:image in every way. Either form is accepted; they behave the same.
og:image:secure_url
The HTTPS version of the image URL. Some older platform crawlers required a separate secure_url for HTTPS images. In practice, og:image on an HTTPS URL is sufficient for all current platforms. Include it as a duplicate of og:image for maximum compatibility with legacy crawlers.
<meta property="og:image:secure_url" content="https://www.example.com/card.png" />og:image:type
The MIME type of the image. Tells the platform what format to expect before it downloads the file. image/png, image/jpeg, image/gif, image/webp are all valid. Prevents platforms from rejecting an unfamiliar extension.
<meta property="og:image:type" content="image/png" />og:image:width and og:image:height
Declared dimensions of the image in pixels. The platform uses them to allocate space in the card layout without fetching the image first. Without them, some platforms skip the image while they wait to measure it, and the card renders without an image until the cache is populated. Minimum recommended size is 1200 by 630 pixels at a 1.91:1 ratio.
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />og:image:alt
Alternative text for the image. Read by screen readers when the share card is encountered in an accessible context. Describes what the image contains. An empty alt is not valid here — write a real description or omit the tag.
<meta property="og:image:alt" content="A diagram showing LCP, CLS, and INP scores on a PageSpeed report." />Video tags
Used when the primary content of the page is a video. Platforms like Facebook can render an inline playable video card when these are present instead of a static image card. All video tags work the same way as their image equivalents — each is a sub-property of og:video.
<meta property="og:video" content="https://www.example.com/video.mp4" />
<meta property="og:video:secure_url" content="https://www.example.com/video.mp4" />
<meta property="og:video:type" content="video/mp4" />
<meta property="og:video:width" content="1280" />
<meta property="og:video:height" content="720" />The spec also defines og:video:url as an alias for og:video — identical in behavior.
Set og:type to video.movie, video.episode, video.tv_show, or video.other when using video tags. The type signals to the platform that video playback is the intended behaviour.
Video-type pages support additional sub-properties for cast and production metadata:
<!-- Applies to video.movie and video.episode -->
<meta property="video:actor" content="https://www.example.com/actor/" />
<meta property="video:actor:role" content="Lead Role" />
<meta property="video:director" content="https://www.example.com/director/" />
<meta property="video:writer" content="https://www.example.com/writer/" />
<meta property="video:duration" content="7200" />
<meta property="video:release_date" content="2026-01-01T00:00:00Z" />
<meta property="video:tag" content="Drama" />
<meta property="video:tag" content="Thriller" />
<!-- video.episode only — points to the parent series page -->
<meta property="video:series" content="https://www.example.com/show/" />- video:actor. URL to the actor's profile page. Multiple actors use multiple tags.
video:actor:roleis a sub-property — pair it with the preceding actor tag. - video:director / video:writer. URLs to profile pages. Multiple allowed via multiple tags.
- video:duration. Runtime in seconds as an integer.
- video:release_date. ISO 8601 timestamp of release.
- video:tag. Genre or topic tags. One tag per
video:tagelement. - video:series. For
video.episodeonly. URL to the parent show page.
Audio tags
For pages where audio is the primary content — podcast episodes, music tracks, audio articles. Most platforms do not render an audio player in the card; support here is thinner than image or video. The tags still carry weight for completeness and for non-browser consumers like podcast aggregators that parse the page directly.
<meta property="og:audio" content="https://www.example.com/episode.mp3" />
<meta property="og:audio:secure_url" content="https://www.example.com/episode.mp3" />
<meta property="og:audio:type" content="audio/mpeg" />The spec defines og:audio:url as an alias for og:audio — identical in behavior.
Article tags
Only valid when og:type is set to article. These give platforms the editorial metadata they need to display article-specific context in the card — publication date, author, section. Facebook and LinkedIn consume these to label articles with publishing context.
<meta property="og:type" content="article" />
<meta property="article:published_time" content="2026-06-22T00:00:00Z" />
<meta property="article:modified_time" content="2026-06-22T00:00:00Z" />
<meta property="article:expiration_time" content="2027-06-22T00:00:00Z" />
<meta property="article:author" content="https://www.example.com/author/" />
<meta property="article:section" content="Technology" />
<meta property="article:tag" content="SEO" />
<meta property="article:tag" content="Performance" />- article:published_time. Full ISO 8601 timestamp. Sets the publication date shown on cards that display it.
- article:modified_time. When the content was last updated. Some platforms show "Updated X days ago" from this.
- article:expiration_time. When the content becomes stale. Rarely used — only relevant for time-sensitive content like promotions or event coverage.
- article:author. URL to the author's profile page. One tag per author. Multiple authors use multiple tags.
- article:section. The editorial section — "Technology", "Finance", "Opinion". One section per article.
- article:tag. Topic tags for the article. Multiple allowed — one tag per
article:tagelement.
Book tags
Only valid when og:type is book. Used on book pages, review pages, and author sites.
<meta property="og:type" content="book" />
<meta property="book:author" content="https://www.example.com/author/" />
<meta property="book:isbn" content="978-0-123456-78-9" />
<meta property="book:release_date" content="2026-01-01T00:00:00Z" />
<meta property="book:tag" content="Programming" />
<meta property="book:tag" content="Web Development" />Profile tags
Only valid when og:type is profile. Used on personal profile pages and author bio pages. profile:username is the most commonly consumed — some platforms display it as a handle on the card.
<meta property="og:type" content="profile" />
<meta property="profile:first_name" content="Nitish" />
<meta property="profile:last_name" content="Kumar" />
<meta property="profile:username" content="sudonitish" />
<meta property="profile:gender" content="male" />profile:gender accepts male or female. It is part of the original Facebook Open Graph spec and is rarely used today.
Music tags
Used when og:type is one of the music types. music.song for individual tracks, music.album for albums, music.playlist for playlists, music.radio_station for streams.
<!-- For a song page -->
<meta property="og:type" content="music.song" />
<meta property="music:duration" content="245" />
<meta property="music:album" content="https://www.example.com/album/" />
<meta property="music:album:disc" content="1" />
<meta property="music:album:track" content="3" />
<meta property="music:musician" content="https://www.example.com/artist/" /><!-- For an album page -->
<meta property="og:type" content="music.album" />
<meta property="music:song" content="https://www.example.com/track-one/" />
<meta property="music:song:disc" content="1" />
<meta property="music:song:track" content="1" />
<meta property="music:musician" content="https://www.example.com/artist/" />
<meta property="music:release_date" content="2026-01-01T00:00:00Z" />- music:duration. Track length in seconds as an integer.
- music:album and music:song. URLs pointing to the album or song page. One tag per item — multiple songs use multiple tags.
For music.playlist and music.radio_station types, music:creator replaces music:musician as the artist reference:
<!-- For a playlist page -->
<meta property="og:type" content="music.playlist" />
<meta property="music:song" content="https://www.example.com/track-one/" />
<meta property="music:song:disc" content="1" />
<meta property="music:song:track" content="1" />
<meta property="music:creator" content="https://www.example.com/artist/" /><!-- For a radio station page -->
<meta property="og:type" content="music.radio_station" />
<meta property="music:creator" content="https://www.example.com/artist/" />Twitter and X cards
Twitter's card system predates OpenGraph and uses name instead of property attributes. Twitter reads its own tags first, then falls back to OpenGraph equivalents when its tags are absent. Set both for maximum compatibility.
twitter:card
The most important Twitter tag. Controls the card format. Without it, Twitter may not render any card at all.
<meta name="twitter:card" content="summary_large_image" />- summary. Small square thumbnail on the left, title and description on the right. Default for most content.
- summary_large_image. Full-width image above the title and description. Use this for visual content — blog posts, product pages, articles.
- app. A card for mobile apps. Shows the app icon, name, description, and download links for iOS and Android.
- player. An inline video or audio player. Requires Twitter approval and a valid
httpsembed URL.
twitter:site
The Twitter handle of the site or publisher. Shown as a label on some card formats. The @ is required.
<meta name="twitter:site" content="@sitehandle" />twitter:site:id accepts the numeric Twitter user ID as an alternative to the handle. The handle works everywhere — the ID is rarely needed.
<meta name="twitter:site:id" content="123456789" />twitter:creator
The Twitter handle of the individual who wrote the content. Different from twitter:site when the author and the publisher are separate accounts. The @ is required.
<meta name="twitter:creator" content="@authorhandle" />twitter:creator:id accepts the numeric user ID as an alternative. Same as twitter:site:id — the handle is sufficient.
<meta name="twitter:creator:id" content="123456789" />twitter:title
The card headline. Falls back to og:title when absent. Keep it under 70 characters — Twitter truncates longer titles.
<meta name="twitter:title" content="How to Fix Core Web Vitals" />twitter:description
The card summary. Falls back to og:description when absent. Keep it under 200 characters.
<meta name="twitter:description" content="LCP, CLS, INP — what they measure and how to fix each one." />twitter:image
The card image. Falls back to og:image when absent. Same rules apply — absolute URL, public access, no expiring signed URLs.
<meta name="twitter:image" content="https://www.example.com/card.png" />twitter:image:alt
Alternative text for the Twitter card image. Twitter actively promotes accessibility — this tag is checked by Twitter's own accessibility guidelines. Keep it under 420 characters.
<meta name="twitter:image:alt" content="A diagram showing LCP, CLS, and INP scores." />twitter:player (video cards)
Used with twitter:card set to player. Requires prior approval from Twitter and a valid HTTPS iframe URL. Renders an inline media player directly in the tweet.
<meta name="twitter:card" content="player" />
<meta name="twitter:player" content="https://www.example.com/embed/video/" />
<meta name="twitter:player:width" content="1280" />
<meta name="twitter:player:height" content="720" />
<meta name="twitter:player:stream" content="https://www.example.com/stream/video.mp4" />twitter:player:stream is the direct URL to the media file for inline playback, separate from the embed iframe URL in twitter:player.
twitter:app (app cards)
Used with twitter:card set to app. Shows iOS and Android app download links in the card. Each platform needs its own set of tags.
<meta name="twitter:card" content="app" />
<meta name="twitter:app:name:iphone" content="App Name" />
<meta name="twitter:app:id:iphone" content="123456789" />
<meta name="twitter:app:url:iphone" content="myapp://content/page" />
<meta name="twitter:app:name:ipad" content="App Name" />
<meta name="twitter:app:id:ipad" content="123456789" />
<meta name="twitter:app:url:ipad" content="myapp://content/page" />
<meta name="twitter:app:name:googleplay" content="App Name" />
<meta name="twitter:app:id:googleplay" content="com.example.app" />
<meta name="twitter:app:url:googleplay" content="myapp://content/page" />The image requirements
The preview image has rules of its own, and missing them is the most common reason an image is cropped or dropped.
- Dimensions. Minimum 1200 by 630 pixels. The ratio should sit close to 1.91:1, or the image gets cropped or rejected.
- File size. Facebook's crawler will not load images over 8MB. Keep images under 1MB for fast crawling.
- Format. PNG and JPEG are universally supported. WebP works on most modern platforms. GIF is supported but only the first frame is shown — it does not animate.
- Access. Must be reachable at a public URL. No authentication, no redirects that break crawlers, no signed URL that expires.
- Location. Serve from the same domain or a CDN. A path that requires a token or sits behind a login will not load for the crawler.
- Safe zone. Keep important content in the centre 80% of the image. Some platforms crop to a square thumbnail in certain contexts.
Where it breaks for developers
The same few mistakes appear on almost every site that ships with broken cards.
- Tags set client-side. Crawlers see no tags because the JavaScript that adds them has not run. Render the tags on the server.
- Relative image URLs.
og:imagemust be absolute.https://www.example.com/card.pngworks./card.pngdoes not. - Missing dimensions. Some platforms skip the image entirely while they fetch it to measure it. Declare width and height.
- A cached wrong card. Platforms cache aggressively. After fixing the tags, the old card can persist for hours or days. Force a refresh through the platform debug tool rather than waiting.
- Different environments. A staging URL in
og:urlcan pollute the production cache. Always setog:urlto the canonical production URL at build time. - Missing twitter:card. Twitter does not render a card without this tag, even when all OpenGraph tags are present and correct.
How to test it
Test before sharing, not after. Each platform exposes a tool that shows the card it will render and clears its cache.
- OpenGraph preview. OpenGraph.xyz shows the card as each platform renders it, in one view.
- LinkedIn. The Post Inspector gives a LinkedIn-specific preview and refreshes its cache.
- Twitter. Twitter's card validator was deprecated in 2023. Use OpenGraph.xyz to preview how X renders the card, or post a draft tweet and inspect the live preview directly.
- Facebook and WhatsApp. The Sharing Debugger validates the tags and forces a re-scrape for both.
What no tool will warn you about
No tool checks whether the OpenGraph tags are present. No test fails because og:image is missing. No warning fires for a relative image URL or an absent twitter:card. The page deploys, it looks correct in the browser, and the blank card only appears when someone pastes the URL somewhere public.
By then the share has already happened. The fix is specific and the tools exist, but nothing in the workflow points at the gap until the gap is already in front of an audience.