Open Graph Meta Tags: What They Are, Why They Matter, and How to Set Them Up
10 April, 2026 Web
Open Graph Meta Tags: What They Are, Why They Matter, and How to Set Them Up
I shared a blog post on LinkedIn last year and the preview showed my site's cookie banner as the image, the homepage title instead of the article title, and no description at all. The post got zero engagement. The content was good — the meta tags were broken. That one broken share cost me a week of promotion effort. Open Graph tags are the invisible layer that controls how your content appears to the world, and getting them wrong is easier than you think.
What Is the Open Graph Protocol
Facebook introduced the Open Graph protocol in 2010 at their f8 conference. The idea was simple: let web pages declare themselves as objects in a social graph using <meta> tags in the HTML <head>. Instead of Facebook's crawler guessing what a page is about by scraping text and images, the page author explicitly states: here is the title, here is the description, here is the image.
The protocol is defined at ogp.me and uses RDFa syntax — specifically the property attribute on <meta> tags, not the name attribute. This distinction matters because some HTML validators flag OG tags as invalid if you use name instead of property. Both work in practice, but property is the correct specification.
What started as a Facebook-only feature is now the de facto standard for link previews across the web. Facebook, LinkedIn, Discord, Slack, Telegram, WhatsApp, Pinterest, and even iMessage all read Open Graph tags. Twitter has its own card format but falls back to OG tags when Twitter-specific tags are absent.
The Four Required Tags
The Open Graph specification defines four tags as required for every page. Without these, a crawler may ignore your OG markup entirely.
| Tag | Purpose | Example |
|---|---|---|
og:title |
The title of your content | My Blog Post Title |
og:type |
The type of content (website, article, product, etc.) | article |
og:image |
An image URL representing the content | https://example.com/img/og.jpg |
og:url |
The canonical URL for the content | https://example.com/blog/my-post |
In practice, og:description is also essential even though the spec lists it as optional. Without it, platforms either show no description or pull random text from your page. Always include all five.
The minimal set of tags for any page:
<meta property="og:title" content="Your Page Title">
<meta property="og:type" content="website">
<meta property="og:image" content="https://example.com/og-image.jpg">
<meta property="og:url" content="https://example.com/page">
<meta property="og:description" content="A concise description of your page.">
Two tags that are technically optional but recommended: og:site_name (your brand name, shown separately from the title on some platforms) and og:locale (defaults to en_US if omitted). You can generate all of these tags with the correct format using the Open Graph Generator.
The og:type System
The og:type tag does more than classify your content — it unlocks type-specific properties. Most developers set website and move on, but choosing the right type enables richer previews and better categorisation.
Common Types
| Type | When to Use | Extra Properties |
|---|---|---|
website |
Homepage, landing pages, tools | None |
article |
Blog posts, news articles | article:published_time, article:author, article:section, article:tag |
product |
E-commerce product pages | product:price:amount, product:price:currency |
profile |
User profile pages | profile:first_name, profile:last_name, profile:username |
video.other |
Video pages | og:video, og:video:type, og:video:width, og:video:height |
music.song |
Music tracks | music:duration, music:album, music:musician |
Article-Specific Tags
For blog posts and news articles, these additional tags provide structured information that platforms can use for display and discovery:
<meta property="og:type" content="article">
<meta property="article:published_time" content="2026-04-06T10:00:00+00:00">
<meta property="article:modified_time" content="2026-04-06T12:30:00+00:00">
<meta property="article:author" content="https://example.com/authors/jane">
<meta property="article:section" content="Technology">
<meta property="article:tag" content="SEO">
<meta property="article:tag" content="Meta Tags">
Facebook uses article:published_time to show the publication date in the link preview. This builds trust — users can see at a glance whether the content is recent or outdated.
Twitter Cards and the Fallback Chain
Twitter (now X) has its own meta tag format called Twitter Cards. The key tag is twitter:card, which determines the layout of the preview. Without this tag, Twitter may show no preview at all — even if all Open Graph tags are present.
| Twitter Card Type | Layout | When to Use |
|---|---|---|
summary |
Small square thumbnail + title + description | Default for most pages |
summary_large_image |
Large image above title + description | Blog posts, articles, landing pages |
player |
Embedded video or audio player | Video/audio content |
app |
App install card with platform buttons | Mobile app promotion |
The fallback chain works like this: Twitter checks twitter:title first, then falls back to og:title, then to <title>. The same applies to twitter:description → og:description → meta description, and twitter:image → og:image.
In practice, most sites only set twitter:card and optionally twitter:site (your Twitter handle), then let everything else fall back to OG tags. This keeps your meta tags DRY:
<!-- Open Graph (used by Facebook, LinkedIn, Discord, Slack, etc.) -->
<meta property="og:title" content="Your Page Title">
<meta property="og:description" content="Your description.">
<meta property="og:image" content="https://example.com/og.jpg">
<meta property="og:url" content="https://example.com/page">
<!-- Twitter-specific (only what can't fall back to OG) -->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="@yourhandle">
Image Specifications Per Platform
Getting the image right is the single most impactful thing you can do for social sharing. A link with a compelling image gets dramatically more clicks than a text-only preview. But each platform has its own requirements, and an image that looks perfect on Facebook may get cropped awkwardly on Twitter.
| Platform | Recommended Size | Aspect Ratio | Min Size | Max File Size |
|---|---|---|---|---|
| 1200 x 630 | 1.91:1 | 200 x 200 | 8 MB | |
| Twitter (large) | 1200 x 628 | 1.91:1 | 300 x 157 | 5 MB |
| Twitter (summary) | 240 x 240 | 1:1 | 144 x 144 | 5 MB |
| 1200 x 627 | 1.91:1 | 200 x 200 | 5 MB | |
| Discord | 1200 x 630 | 1.91:1 | No minimum | 8 MB |
| 1200 x 630 | 1.91:1 | 300 x 200 | 5 MB | |
| 1000 x 1500 | 2:3 | 200 x 200 | 10 MB |
The universal safe choice: 1200 x 630 pixels, JPEG or PNG, under 1 MB. This single image works well on every platform except Pinterest (which prefers vertical images). Keep important content — text, logos, faces — centred and away from edges, because mobile apps crop more aggressively than desktop.
Additional Image Rules
- Always use HTTPS. An
og:imagewith an HTTP URL will be blocked by platforms that enforce mixed content policies. - Use absolute URLs. Relative paths like
/images/og.jpgare silently ignored. The full URL must start withhttps://. - Include
og:image:widthandog:image:height. These tags let platforms render the correct aspect ratio before the image loads, preventing layout shifts in feeds. Without them, some platforms show a blank space until the image downloads. - Specify
og:image:type. Set toimage/jpeg,image/png, orimage/webp. While not strictly required, some platforms use this to pre-validate the image format.
Implementation in Popular Frameworks
PHP (Vanilla)
$ogTags = [
'og:title' => htmlspecialchars($article->title),
'og:description' => htmlspecialchars($article->excerpt),
'og:image' => $article->ogImageUrl,
'og:url' => $article->canonicalUrl,
'og:type' => 'article',
'og:site_name' => 'My Site',
];
foreach ($ogTags as $property => $content) {
echo '<meta property="' . $property . '" content="' . $content . '">' . "\n";
}
Next.js (App Router)
// app/blog/[slug]/page.tsx
export function generateMetadata({ params }) {
const post = getPost(params.slug);
return {
title: post.title,
description: post.excerpt,
openGraph: {
title: post.title,
description: post.excerpt,
url: `https://example.com/blog/${params.slug}`,
type: 'article',
images: [{ url: post.ogImage, width: 1200, height: 630 }],
publishedTime: post.publishedAt,
},
twitter: {
card: 'summary_large_image',
site: '@yourhandle',
},
};
}
Laravel (Blade)
// In your controller
return view('blog.show', [
'post' => $post,
'og' => [
'title' => $post->title,
'description' => $post->excerpt,
'image' => asset('images/og/' . $post->slug . '.jpg'),
'url' => route('blog.show', $post->slug),
'type' => 'article',
],
]);
<!-- In your Blade layout -->
@foreach($og as $property => $content)
<meta property="og:{{ $property }}" content="{{ $content }}">
@endforeach
Cache Invalidation
Every platform caches your OG data after the first fetch. Updating your meta tags does not automatically update the preview. You need to explicitly tell each platform to re-scrape.
| Platform | Debug Tool | Cache Duration | How to Refresh |
|---|---|---|---|
| Sharing Debugger | ~30 days | Click "Scrape Again" | |
| Card Validator | ~7 days | Paste URL and validate | |
| Post Inspector | ~7 days | Click "Inspect" | |
| Discord | No official tool | Until server restart or cache eviction | Re-share the link |
| Telegram | No official tool | Varies | Send the URL to @webpagebot |
| Slack | No official tool | ~1 hour | Wait, or unfurl the link in a new message |
For Facebook specifically, you can also use the API to clear cached data programmatically:
curl -X POST "https://graph.facebook.com/?id=https://example.com/page&scrape=true"
This is useful in deployment scripts — scrape the updated page automatically after each deploy.
Common Mistakes
Having audited hundreds of sites with the Meta Tag Analyser, these are the mistakes I see most frequently:
-
Same OG tags on every page. The homepage title and image are hardcoded in the layout template, overriding page-specific values. Every page shared on social media looks identical.
-
Using
nameinstead ofproperty. Writing<meta name="og:title">instead of<meta property="og:title">. Most platforms accept both, but the Open Graph spec requiresproperty. Some strict parsers rejectname. -
Relative image URLs. Writing
og:imageas/images/og.jpginstead of the fullhttps://example.com/images/og.jpg. Every platform ignores relative paths. -
Missing
twitter:card. Setting all OG tags correctly but forgettingtwitter:card. Twitter shows no preview at all without this tag. -
Images too small. Using a 300x200 image that gets stretched and pixelated on high-DPI screens. Always use 1200x630 minimum.
-
Not testing after deployment. Tags work in development but the production build strips them, a CDN caches the old version, or a server-side rendering issue returns empty tags to crawlers.
-
Forgetting
og:url. Without it, the URL displayed in the preview is whatever URL was shared — which might include tracking parameters, session IDs, or other clutter.
Preview how your links will actually appear with the Social Media Preview tool, and validate that all tags are present with the Meta Tag Analyser.
Quick Reference
The copy-paste template for a complete set of social sharing meta tags:
<!-- Primary Meta Tags -->
<title>Your Page Title</title>
<meta name="description" content="Your page description.">
<link rel="canonical" href="https://example.com/page">
<!-- Open Graph -->
<meta property="og:type" content="website">
<meta property="og:url" content="https://example.com/page">
<meta property="og:title" content="Your Page Title">
<meta property="og:description" content="Your page description.">
<meta property="og:image" content="https://example.com/og-image.jpg">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta property="og:site_name" content="Your Site Name">
<!-- Twitter -->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="@yourhandle">
Generate this markup for any page in seconds with the Open Graph Generator. If your page titles need clean URL slugs, generate those too.