Open Graph Preview
Compose Open Graph and Twitter card tags and preview the card locally — nothing is fetched, nothing uploaded.
After this page loads it issues no network requests: your URL is never fetched, the image URL is never loaded, and no platform is contacted. Check your network tab.
0 meta tags read · 0 B
Wide 1.91:1 image above the text on X.
Pick the file you will publish as og:image. It is measured on this device and never uploaded — and the URL above is never fetched, so only a picked file can be shown.
An approximation drawn from your tags, not a screenshot — this page never contacts a platform.
Modelled on Facebook's documented sharing-debugger layout and its published og:image guidance (1200×630, 1.91:1). Modelled layout, derived 2026-08.
Platforms re-crawl on their own schedule and cache aggressively, so this is what your tags say — not what a platform will show today.
- 5 values were written as character references — the attribute rule escapes every non-alphanumeric code point below U+0100. A parser decodes every escape before a platform reads it, so the markup parses back to the text you typed.
Press ? for shortcuts ·
Do it offline:$ python3 -c "import html.parser,sys;h=html.parser.HTMLParser();h.handle_starttag=lambda t,a:[print(d.get('property') or d.get('name'),'=',d.get('content')) for d in [dict(a)] if t=='meta' and (d.get('property') or d.get('name','')).startswith(('og:','twitter:'))];h.feed(open(sys.argv[1],encoding='utf-8').read())" page.html
How to use it
- Pick a mode: Compose opens on a worked example you type over, Paste page source reads the tags already in markup you copied from view-source.
- Type the title, description, image URL, page URL and site name. Every keystroke re-emits the head block and redraws the card; unset fields stay listed under Missing.
- Choose a platform row and read the card. Drop the image file and its pixels and weight are measured here against the published 1200×630 floor and 5 MB ceiling.
- Copy the head block into your document head. Re-sharing forces nothing — each platform re-crawls on a schedule of its own.
Fill in the fields — or paste your page source — and this page writes the Open Graph and Twitter card meta tags, then draws the link card five platforms would build from them. Nothing is fetched: no URL is loaded, no image is uploaded, no platform is contacted. Open the DevTools Network panel while you work and the request log stays empty.
How it works
Pasted markup is walked as a token stream by the shared HTML tokenizer, never searched with a pattern. So a meta element inside a script stays raw text, an unquoted value is read as written, and a tag running off the end survives verbatim. One inside noscript is read; one inside a template is read too, though no platform uses it. Values decode through the shared character-reference table, and every tokenizer remark comes back with its line and column — nothing is quietly repaired.
Card geometry is frozen data, one row per platform, each naming the documented layout it models and the month it was derived. Facebook clips titles at 88 characters, X at 70 on a single line, LinkedIn shows no description at all, Discord publishes 256 and 350, Slack allows three description lines. Those numbers clamp the preview only; the tags emitted here are never shortened.
Examples
Compose: title, description, image, URL, site name, website, large card<meta property="og:title" content="Devxcode — developer tools">
<meta property="og:description" content="Fast, local developer utilities.">
<meta property="og:image" content="https://example.com/og.png">
<meta property="og:url" content="https://example.com/">
<meta property="og:site_name" content="Devxcode">
<meta property="og:type" content="website">
<meta name="twitter:card" content="summary_large_image">Seven tags, 517 bytes, exactly what the copy button emits. Punctuation inside a value becomes a numeric character reference — the strict attribute rule — which a parser undoes first.
Paste source: og:type on name=, relative image, no og:descriptiondescription (name, unused) = Fast, local developer utilities.
og:title (property) = Devxcode & friends
og:image (property) = /og.png
og:type (name) = webpage
missing: og:description, og:url
N_OG_NAME_VS_PROPERTY · `og:type` is on `name=` at line 9, column 1; the Open Graph protocol puts it on `property=`. It is read here and the major platforms read it too — nothing was changed.
N_OG_FALLBACK_USED · No `og:description` was found, so `<meta name="description">` at line 6, column 1 filled it. Platforms do fall back to it, but an explicit `og:description` is the one you control.A real page head, read back. og:description stays on the missing list even though the fallback filled the field: that tag is genuinely absent.
Preview: a 91-character title on the X templateOpen Graph Preview — compose the tags, preview the card, and ship the…
Write the fields or paste your page source; the card redraws as you type.
example.com
N_OG_TRUNCATED_PREVIEW · This preview clips the title at 70 characters, modelled on x (2026-08). The tags this page emits are never truncated — only the preview is.Title, description, host, note. X's single line holds 70 characters, so the ellipsis names its template and month; og:title still carries all 91.
Check: a 600×315 AVIF weighing 6 MBW_IMG_BELOW_MINIMUM · The image is 600×315; the documented minimum for a large card is 1200×630. Below it, platforms either upscale it or drop back to the small card.
W_IMG_OVER_SIZE_LIMIT · The image is 6.0 MB; the documented ceiling is 5 MB. Over it, platforms skip the image and render a text-only card.
N_IMG_TYPE_UNCOMMON · The image is `image/avif`. Every platform here documents image/jpeg, image/png, image/gif, image/webp — anything else may be ignored even when a browser renders it.Three findings from one file: half the documented pixel floor, a megabyte over the ceiling, an unlisted format. Nothing is converted or resized.
Edge case: a title containing & " < > straight from a CMS<meta property="og:title" content="Tips & tricks: "<script>" in a title">
<meta property="og:description" content="Ampersands, quotes and angle brackets, straight from a CMS.">
<meta property="og:url" content="https://example.com/tips">
3 values were written as character references — the attribute rule escapes every non-alphanumeric code point below U+0100. A parser decodes every escape before a platform reads it, so the markup parses back to the text you typed.Why a title is escaped rather than concatenated: those quotes cannot close the attribute, those brackets cannot open a tag, and the block still re-parses to the original string.
Every example on this page is executed against the same engine that powers the tool, on every build.
Gotchas worth knowing
A preview is what your tags say, not what a platform will show
Each card is a modelled approximation naming its basis and month. A platform that already crawled your URL serves its cache until its own schedule expires, so a correct preview and a stale unfurl disagree for hours.
Repeating a property is legal, and the first one wins
Several og:image entries are allowed, so a second is reported rather than removed, with its position.
Relative and http image URLs both cost you the picture
Platforms load og:image from their own servers, where /og.png resolves against nothing, and several refuse insecure URLs. Guessing your origin would be inventing data.
Declared dimensions are read, and odd markup still extracts
og:image:width, og:image:height and og:image:type feed the same check as a dropped file, and are written back out unchanged.
Common errors
There is no `og:title`, so every platform falls back to your `<title>` or to the URL itself. Set it to the headline you want on the card.- Not a failure — the card renders with whatever the page title is, usually a string written for search.
`twitter:card` is `summary_large_image` but there is no image, so X falls back to the small `summary` card. Add an `og:image` or set the card to `summary`.- Card type and image are separate declarations and only one was made. Fill the image, or pick the small card.
`og:image` is “/og.png”, which is relative. Platforms fetch it from their own servers, so it must be an absolute URL beginning with `https://`.- A root-relative path works in a browser because it knows the site. A crawler resolving it against its own host finds nothing.
The image is 600×315; the documented minimum for a large card is 1200×630. Below it, platforms either upscale it or drop back to the small card.- The right shape at half the resolution: soft on modern displays, and rejected by some platforms.
`og:type` is “webpage”, which is not in the vocabulary published at ogp.me. Custom namespaced types are legal — this is a heads-up, not an error; `website` and `article` cover almost every page.- The plausible value is the trap — the published vocabulary spells it website. Custom namespaced types stay legal, so it is kept and named.
Input is larger than the 1 MB limit for this tool.- A megabyte is refused before parsing rather than trimmed: a shortened head would report tags you do not have. Run the printed command instead.
FAQ
Why can't I just paste my URL and have it checked?
A browser cannot read another site's page from this one, and routing that through our server would send your URLs to us. Paste the source instead — the extraction is identical.
Why is my copied head block full of   escapes?
Every value takes the strict attribute rule, encoding each non-alphanumeric character below U+0100 rather than the four that could break the quotes. Verbose, and lossless.
What size should og:image actually be?
1200×630 or larger, near 1.91:1, under 5 MB — the figures Facebook and X publish for the large card. Squares are accepted but centre-cropped, and the crop is named here first.
I fixed my tags but the old card still shows — why?
Platforms cache what they crawled and re-crawl on their own schedule, so an updated head can take hours to surface. Their own debugger forces a refetch; this page cannot press it.
Keyboard shortcuts
- ⌘/Ctrl + Enter
- Re-run extraction and redraw every card.
- ⌘/Ctrl + S
- Download the head block as an .html file.
- ⌘/Ctrl + C
- Copy the head block when nothing is selected.
- ⌘/Ctrl + Shift + C
- Copy the head block even with a selection.
- t
- Cycle the color theme, ignored while typing.
- ? or ⌘/Ctrl + /
- Open the keyboard shortcut overlay.
- Esc
- Close the topmost dialog; your input stays put.