Open Graph tags control how your URLs appear when shared on social platforms. Getting them right is non-trivial: each platform has its own crawler, its own caching behavior, and its own rules for which tags it reads and ignores. Validating OG tags means simulating what each crawler sees — not what your browser renders — and checking that against each platform's documented constraints.
Why Browser DevTools Are Not Enough
When you inspect your page's <head> in Chrome DevTools, you are seeing the DOM after JavaScript has run. Social crawlers don't run JavaScript. They make a plain HTTP request, read the raw HTML, and extract meta tags from that. If your OG tags are injected by a React component, set by react-helmet, or updated dynamically after page load, crawlers may see nothing — even though DevTools shows the correct tags.
The correct way to validate OG tags is to fetch your page server-side, exactly as each crawler does, and inspect the HTML response before any JavaScript executes.
How Each Platform's Crawler Works
Twitter / X (Twitterbot)
- —User-Agent: Twitterbot/1.0
- —Reads twitter:* tags first, falls back to og:* tags.
- —twitter:card is required — without it, Twitter may not render a card at all.
- —Caches previews per URL. No official cache-purge tool; append a query string (?v=2) to force a fresh fetch.
- —Does not execute JavaScript.
LinkedIn (LinkedInBot)
- —User-Agent: LinkedInBot/1.0 (compatible; LinkedInBot/1.0; +http://www.linkedin.com)
- —Reads only og:* tags — ignores all twitter:* tags.
- —Aggressively caches for up to 7 days. Use the LinkedIn Post Inspector to force a re-crawl.
- —Images below 200×200px are hidden entirely.
- —Does not execute JavaScript.
Facebook (facebookexternalhit)
- —User-Agent: facebookexternalhit/1.1 (+http://www.facebook.com/externalhit_uatext.php)
- —Reads og:* tags. Also reads article:* namespace tags for article og:type.
- —Caches for ~30 days. Use the Facebook Sharing Debugger to force a re-crawl.
- —Images below 200×200px are not shown; below 600×315px are shown as small thumbnails.
- —Does not execute JavaScript.
Discord (Discordbot)
- —User-Agent: Discordbot/2.0 (+https://discordapp.com)
- —Reads og:* tags. Also reads theme-color meta tag for embed accent color.
- —Supports og:video for inline video embeds.
- —Re-fetches automatically after a few minutes. Paste the URL again to refresh.
- —Does not execute JavaScript.
Slack (Slackbot)
- —User-Agent: Slackbot-LinkExpanding 1.0 (+https://api.slack.com/robots)
- —Reads og:* and twitter:* tags. Uses twitter:card to determine image size.
- —Without twitter:card="summary_large_image", shows a small thumbnail rather than a large image.
- —Workspace admins can disable link unfurling per-domain.
- —Does not execute JavaScript.
What to Validate for Each OG Tag
og:title
- —Present and non-empty
- —Twitter: max 70 characters before truncation
- —LinkedIn: max 150 characters
- —Facebook: max ~100 characters in feed
- —Avoid HTML entities — write "Don't" not "Don't"
og:description
- —Present and non-empty
- —Twitter: max ~200 characters
- —LinkedIn: max ~300 characters
- —Facebook: max ~300 characters in most surfaces
- —Target 150 characters — safe across all platforms
og:image
- —Absolute URL (starts with https://)
- —Returns HTTP 200 with an image Content-Type
- —Publicly accessible without authentication
- —Minimum 200×200px for LinkedIn and Facebook; 300×157px for Twitter
- —Recommended: 1200×630px (works on all platforms)
- —Include og:image:width and og:image:height to prevent layout shift
og:url
- —Should match the canonical URL of the page
- —Platforms use this for deduplication — mismatched og:url can cause ghost entries or broken sharing counts
twitter:card
- —Required for Twitter to render a card — without it, Twitter may show no preview
- —"summary_large_image" for landscape images (1200×628), "summary" for square (400×400)
- —Slack also respects twitter:card for image display mode
Platform-Specific Validation Tools
Each major platform provides an official debugger. These are useful for forcing cache re-crawls after you fix OG tags:
- —Twitter/X — twitter.com/cards/validator (may require login). Alternatively, append ?v=2 to your URL and post again.
- —Facebook — developers.facebook.com/tools/debug — shows what Facebook's crawler sees and lets you "Scrape Again" to force a re-fetch.
- —LinkedIn — linkedin.com/post-inspector — enter any URL to see what LinkedIn will display and force a cache refresh.
- —Discord — no official tool. Just paste the URL in a test server and wait a few minutes for Discord to re-fetch.
- —Slack — no official tool. Paste the URL in a direct message to yourself.
Manual Validation with curl
You can simulate any crawler with curl by setting the User-Agent header. This shows you exactly what the crawler receives, with no JavaScript execution:
# Fetch as Twitterbot and extract OG tags
curl -s -A "Twitterbot/1.0" "https://example.com/your-page" \
| grep -i '<meta.*og:\|<meta.*twitter:'
# Fetch as LinkedInBot
curl -s -A "LinkedInBot/1.0" "https://example.com/your-page" \
| grep -i '<meta.*og:'
# Fetch as facebookexternalhit
curl -s -A "facebookexternalhit/1.1" "https://example.com/your-page" \
| grep -i '<meta.*og:'
# Fetch as Discordbot
curl -s -A "Discordbot/2.0" "https://example.com/your-page" \
| grep -i '<meta.*og:\|<meta.*theme-color'If the grep returns nothing for og:image, your tags are either missing from the server response or being injected by JavaScript after the initial HTML. If the URL returns a redirect, follow it with curl -L.
Common Validation Failures and Their Fixes
- 1.og:image missing from server HTML — tags are being set by JavaScript. Fix: use SSR (Next.js Metadata API, generateMetadata()).
- 2.og:image is an HTTP URL — upgrade to HTTPS. Twitter and iMessage will not display HTTP images.
- 3.og:image returns 403 to crawlers — the image host is blocking non-browser user agents. Fix: allow all user agents, or move the image to a public CDN.
- 4.twitter:card not set — Twitter renders a text-only card or no card at all. Fix: add <meta name="twitter:card" content="summary_large_image" />.
- 5.og:url points to a different domain — some platforms use og:url instead of the actual URL for deduplication. Fix: set og:url to the exact canonical URL.
- 6.og:description over 150 characters — will be truncated differently per platform. Fix: write a 100–150 character description.
- 7.Image ratio wrong for Twitter — you have a square image but twitter:card="summary_large_image". Fix: switch to twitter:card="summary" or use a 2:1 landscape image.
Automating OG Validation in CI
For teams that deploy frequently, running a manual validation check after every deploy is impractical. You can automate basic checks with a simple script that runs in your CI pipeline:
#!/bin/bash
# validate-og.sh — run after deploy to check critical OG tags
URL="$1"
if [ -z "$URL" ]; then
echo "Usage: ./validate-og.sh https://example.com/page"
exit 1
fi
HTML=$(curl -s -A "Twitterbot/1.0" "$URL")
check_tag() {
local tag="$1"
local label="$2"
if echo "$HTML" | grep -qi "$tag"; then
echo "✓ $label"
else
echo "✗ $label MISSING" && FAILED=1
fi
}
check_tag 'og:title' 'og:title'
check_tag 'og:description' 'og:description'
check_tag 'og:image' 'og:image'
check_tag 'og:url' 'og:url'
check_tag 'twitter:card' 'twitter:card'
if [ "$FAILED" = "1" ]; then
echo "OG validation failed."
exit 1
fi
echo "All OG tags present."This script only checks for presence — it does not validate image dimensions, HTTPS, or truncation. For full validation including per-platform rendering, the OGProof API provides a programmatic endpoint that returns structured validation results for all six platforms.
OGProof: Validate All Six Platforms at Once
OGProof was built specifically to solve the multi-platform validation problem. Paste any URL and it fetches your page server-side (with no JavaScript execution), parses all OG, Twitter Card, and meta tags, and renders accurate previews for all six platforms: Twitter, LinkedIn, Facebook, Discord, Slack, and iMessage.
- —Server-side fetch — sees exactly what each crawler sees, not what your browser renders
- —Per-platform validation — each tag is checked against each platform's documented constraints
- —Visual previews — see the rendered card, not just raw tag values
- —Fix suggestions — specific, actionable errors when tags are missing or invalid
- —Free to start — validate any public URL, no account required