OGKit

Why your Open Graph card is blank

  • open-graph
  • debugging

You paste your link into Slack and get a bare URL. You paste it into X and get a plain text row. The tag is right there in your template, so what happened?

In practice a blank card is rarely a missing og:image. It is usually one of five things, and they are easy to tell apart once you know what to look for.

1. The image URL is relative

The Open Graph spec wants an absolute URL. A relative one resolves fine in a browser and fails everywhere else, because the crawler has no document base to resolve it against.

<!-- Silently broken -->
<meta property="og:image" content="/static/card.png" />

<!-- Correct -->
<meta property="og:image" content="https://example.com/static/card.png" />

The same rule applies to og:url. See og-image-relative-url for the exact check.

2. The tags are injected by JavaScript

Most crawlers do not run your JavaScript. If your meta tags are added by a client-side router or an analytics-style script after hydration, the crawler sees the shell and nothing else.

Curl the page and read what actually came over the wire:

curl -sL https://example.com/post | grep -i 'og:'

If the tags are absent from that output, they do not exist as far as sharing is concerned. Render them on the server.

3. The crawler is being blocked

A robots.txt rule, an X-Robots-Tag header, a WAF, or a CDN bot filter can all return a 403 to a platform's crawler while your browser loads the page normally. This is the single most confusing failure mode, because everything looks right when you check it yourself.

The tell is that the page loads for you but the platform debugger reports a fetch error. Compare a normal request against a crawler user agent:

curl -sI -A "facebookexternalhit/1.1" https://example.com/post

4. The image itself fails to load

The tag can be perfectly formed and point at an asset that 404s, redirects through a signed-URL flow, sits behind auth, or is served with a MIME type the platform will not decode. Platforms fail closed here: no image, no card.

Dimensions matter too. Under roughly 200×200 most platforms will refuse to render a large card, and very large files time out before they are fetched.

5. The old scrape is cached

If the first crawl of a URL happened before your tags were correct, the platform may serve that cached result for days. Fixing the page does not invalidate the cache — you have to ask for a re-scrape.

Each platform has its own debugger and its own cache lifetime; the rescrape helper links to all of them for a given URL.

Telling them apart quickly

Symptom Likely cause
Card works in browser preview, not on platform JS-injected tags, or crawler blocked
Text renders, image missing Image URL relative, 404, or too small
Everything correct in source, card still stale Cached scrape
One platform works, another does not Per-platform size or format limits

The general method is the same regardless: look at the raw HTML the crawler receives, not the DOM your browser built, then confirm the image URL is fetchable in isolation.

That is roughly what OGKit automates — it fetches as a crawler, checks the image, and reports the specific rule that failed. The full list of checks lives in the rule reference.