Open Graph Protocol - The Complete Reference for Developers
The Open Graph protocol was introduced by Facebook in 2010 at f8. It extends HTML with <meta> tags that turn any URL into a rich, structured object in the social graph. Every time someone shares a link on Facebook, LinkedIn, Slack, Discord, Telegram, WhatsApp, or iMessage, the platform's crawler fetches your page, reads these tags, and builds a visual preview card. Without them, platforms guess from page content - and they almost always guess wrong.
The Core Tags
The OG specification defines four required properties. In practice, og:description and og:site_name are equally important for a complete preview.
| Property | Purpose | Example |
|---|---|---|
og:title | Title shown in the link preview (keep under 60 chars) | My Awesome Page |
og:type | Content type - controls which additional tags are available | website, article, product |
og:image | Preview image URL (must be absolute, 1200x630px recommended) | https://example.com/img.jpg |
og:url | Canonical URL - the URL you want shared, not the current page URL | https://example.com/page |
og:description | One or two sentence summary (keep under 155 chars) | A brief description of the page. |
og:site_name | Your website name - displayed above or below the title | My Website |
og:locale | Language and territory in the format language_TERRITORY | en_GB, fr_FR, de_DE |
Type-Specific Tags
When og:type is set to article, additional properties become available that help platforms understand the content better:
article:published_time- ISO 8601 datetime when the article was first publishedarticle:modified_time- when the article was last updatedarticle:author- URL of the author's profile pagearticle:section- the high-level category (e.g., "Technology")article:tag- content tags (can be repeated for multiple tags)
For e-commerce, og:type=product unlocks product:price:amount and product:price:currency, though most platforms do not render these visually. The practical value of type-specific tags is in rich pin support on Pinterest and in structured categorisation by Facebook's algorithm.
Twitter Card Tags and the Fallback Chain
Twitter (now X) has its own meta tag system using <meta name="twitter:...">. The critical tag is twitter:card which controls the card layout: summary shows a small square thumbnail with title and description beside it, while summary_large_image displays a wide image above the text. Without twitter:card, Twitter falls back to OG tags but may display a plain text link with no image at all.
The fallback chain: Twitter first checks twitter:title, then falls back to og:title, then to <title>. The same applies to description and image. This means you can set OG tags and only add twitter:card to control the layout - you do not need to duplicate every value in Twitter-specific tags.
Image Specifications by Platform
| Platform | Recommended Size | Aspect Ratio | Max File Size | Formats |
|---|---|---|---|---|
| 1200 x 630 | 1.91:1 | 8 MB | JPEG, PNG, GIF, WebP | |
| Twitter (large image) | 1200 x 628 | 1.91:1 | 5 MB | JPEG, PNG, GIF, WebP |
| Twitter (summary) | 240 x 240 | 1:1 | 5 MB | JPEG, PNG, GIF, WebP |
| 1200 x 627 | 1.91:1 | 5 MB | JPEG, PNG | |
| 600 x 315 | 1.91:1 | 5 MB | JPEG, PNG |
Key rule: image URLs must be absolute (starting with https://). Relative paths are silently ignored by every platform. JPEG is recommended for photographs, PNG for graphics with text overlays.
Server-Side Implementation
OG tags should be rendered server-side, not injected by JavaScript. Social media crawlers do not execute JavaScript (with rare exceptions). Here is a minimal PHP example:
<head>
<meta property="og:title" content="<?= htmlspecialchars($title) ?>" />
<meta property="og:description" content="<?= htmlspecialchars($description) ?>" />
<meta property="og:image" content="<?= htmlspecialchars($imageUrl) ?>" />
<meta property="og:url" content="<?= htmlspecialchars($canonicalUrl) ?>" />
<meta property="og:type" content="website" />
<meta name="twitter:card" content="summary_large_image" />
</head>
In Next.js, use the metadata export in your page component. In Laravel, use a Blade layout with @yield('og_title') sections. In WordPress, plugins like Yoast SEO handle this automatically, but you can also add tags directly in your theme's header.php.
Cache Invalidation
Every platform caches link previews aggressively. After updating your OG tags, the old preview persists until the cache expires or you force a refresh:
- Facebook: use the Sharing Debugger - paste your URL and click "Scrape Again". Cache typically lasts 24 hours.
- Twitter/X: use the Card Validator. Twitter's cache updates within minutes of a re-scrape.
- LinkedIn: use the Post Inspector - enter your URL and click "Inspect". Cache can persist for up to 7 days.
- Slack, Discord, Telegram: no official debug tools. Slack refreshes when the URL is posted again after ~30 minutes. Discord's cache is shorter. Telegram caches indefinitely for bots but refreshes for users.
Common Mistakes
- Reusing homepage tags on every page. Each page needs unique
og:title,og:description, and ideally a uniqueog:image. Sharing different pages should show different previews. - Forgetting
twitter:card. OG tags cover Facebook and LinkedIn, but Twitter needs the card type explicitly set to show image previews. - Using relative image URLs.
og:image="/img/preview.jpg"does not work. Crawlers need the full URL:og:image="https://example.com/img/preview.jpg". - Injecting tags with JavaScript. Facebook, Twitter, and LinkedIn crawlers do not execute JS. Tags must be in the initial HTML response from the server.
- Images that are too small. Facebook requires at least 200x200 pixels, but anything under 1200x630 looks poor in the feed. Invest in proper preview images.
Testing Your Tags
After generating your tags with this tool, use our Social Media Preview to see exactly how your link will appear on each platform. Then run your live URL through the Meta Tag Analyser to verify that tags are present and correctly formatted in production.