This site is not affiliated with or endorsed by Cloudflare, Inc. It showcases deployable experiments across most Cloudflare products.
Web Scraping & Parsing

Social Preview Inspector

Preview Open Graph, Twitter/X Cards, and Google snippet fields side by side - social SEO unfurl debugger

Fetch any URL and extract og:*, twitter:*, <title>, and meta description tags with HTMLRewriter. Returns side-by-side preview validation for Twitter/X, Open Graph (Facebook/Slack), and Google search snippets, flagging missing required fields per platform.

Features

  • GET /inspect - extract meta tags and validate per-platform preview requirements
  • Side-by-side Twitter, Open Graph, and Google preview objects
  • Flags missing and fallback fields (e.g. og:title used when twitter:title absent)

API Reference

GET /inspect

Fetch a page and return social preview validation for three platforms.

Prop

Type

Example Request

curl "https://your-worker.workers.dev/inspect?url=https://example.com"

Success Response

{
  "url": "https://example.com/",
  "extracted": { "title": "Example", "description": "...", "openGraph": {}, "twitter": {} },
  "previews": {
    "openGraph": { "platform": "openGraph", "valid": true, "missing": [], "fields": {} },
    "twitter": { "platform": "twitter", "valid": false, "missing": ["image"], "fields": {} },
    "google": { "platform": "google", "valid": true, "missing": [], "fields": {} }
  }
}

Error Codes

  • 400 - INVALID_URL
  • 502 - FETCH_ERROR

Use Cases

  • Debug why a link unfurls incorrectly on Slack, Twitter, or iMessage
  • Audit marketing pages for missing Open Graph or Twitter Card tags
  • Compare Google snippet fields against social preview metadata

Limitations

  • Uses raw HTML fetch; does not execute JavaScript (client-rendered tags may be missing)
  • Single URL per request; no batch inspection
  • Platform validation rules are heuristic, not identical to each platform's renderer

Use in your project

Copy these files into an existing Worker. Prefer Deployment to try the full experiment first. Source: apps/experiments/social-preview-inspector.

DependenciesNoneBindingsNonePlatformHTMLRewriter, Fetch API
import { FETCH_TIMEOUT_MS } from "../constants/defaults";export async function fetchHtml(url: string): Promise<string> {  const controller = new AbortController();  const timeout = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);  try {    const res = await fetch(url, {      headers: {        Accept: "text/html,application/xhtml+xml",        "User-Agent": "social-preview-inspector/1.0",      },      signal: controller.signal,      redirect: "follow",    });    clearTimeout(timeout);    if (!res.ok) {      throw new Error(`Upstream returned HTTP ${res.status}`);    }    return await res.text();  } catch (err) {    clearTimeout(timeout);    if (err instanceof Error && err.name === "AbortError") {      throw new Error("Request timed out");    }    throw err instanceof Error ? err : new Error("Failed to fetch URL");  }}

Deployment

Click the deploy button

Deploy to Cloudflare Workers

Configure bindings

See wrangler.json and the experiment README for required bindings.

Test your deployment

See the experiment README for curl examples.

Local Development

cd apps/experiments/social-preview-inspector
npm install
npm run dev

Configuration

No bindings required beyond the Workers runtime.

Cloudflare Features Used

On this page