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

JSON-LD Extractor

Extract Schema.org JSON-LD structured data from any webpage at the edge - rich results and SEO markup inspection

Fetch a webpage and extract application/ld+json structured data blocks for Schema.org / rich-results debugging from Cloudflare's edge.

Features

  • Parses all script[type="application/ld+json"] blocks
  • Collects @type values including nested @graph
  • Reports invalid JSON blocks without failing the whole response
  • Caps extraction at 25 script blocks
  • Stateless; no bindings required

API Reference

GET /extract

Fetches HTML and returns parsed JSON-LD blocks plus discovered types.

Prop

Type

Example Request

curl "https://your-worker.workers.dev/extract?url=https://www.cloudflare.com"

Success Response

url string

Final page URL after redirects

count number

Number of JSON-LD script blocks found

types string[]

Sorted unique @type values across all blocks (including @graph)

blocks array

Per-block results with index, types, data, and optional parseError

{
  "url": "https://www.cloudflare.com/",
  "count": 2,
  "types": ["Organization", "WebSite"],
  "blocks": [
    {
      "index": 0,
      "types": ["Organization"],
      "data": {
        "@context": "https://schema.org",
        "@type": "Organization",
        "name": "Cloudflare"
      }
    },
    {
      "index": 1,
      "types": ["WebSite"],
      "data": {
        "@context": "https://schema.org",
        "@graph": [{ "@type": "WebSite", "name": "Cloudflare" }]
      }
    }
  ]
}

Error Response

{
  "error": "Expected HTML, got content-type: application/json",
  "code": "NOT_HTML"
}

Error Codes

  • 400 - Missing or invalid url (INVALID_URL)
  • 400 - Response was not HTML (NOT_HTML)
  • 502 - Fetch failed (FETCH_ERROR)

Use Cases

  • Debug rich results / Schema.org markup
  • Inventory Organization, Product, Article entities on a site
  • Complement Open Graph previews with structured data
  • Build SEO auditing tools on Workers

Limitations

  • Does not execute JavaScript-injected JSON-LD
  • Caps extraction at 25 script blocks
  • Does not validate against Schema.org vocabularies
  • Invalid JSON blocks are reported via parseError rather than failing the request

Use in your project

Copy these files into an existing Worker. Prefer Deployment to try the full experiment first. Source: apps/experiments/json-ld-extractor.

DependenciesNoneBindingsNonePlatformFetch API
import { MAX_BLOCKS } from "../constants/defaults";import type { ExtractResponse, JsonLdBlock } from "../types/extract";function collectTypes(value: unknown, out: Set<string>): void {  if (!value || typeof value !== "object") return;  if (Array.isArray(value)) {    for (const item of value) collectTypes(item, out);    return;  }  const obj = value as Record<string, unknown>;  const t = obj["@type"];  if (typeof t === "string") out.add(t);  else if (Array.isArray(t)) {    for (const item of t) {      if (typeof item === "string") out.add(item);    }  }  if (Array.isArray(obj["@graph"])) {    for (const item of obj["@graph"]) collectTypes(item, out);  }}/** * Extract application/ld+json script blocks from HTML. */export function extractJsonLd(url: string, html: string): ExtractResponse {  const re = /<script\b[^>]*type\s*=\s*["']application\/ld\+json["'][^>]*>([\s\S]*?)<\/script>/gi;  const blocks: JsonLdBlock[] = [];  const allTypes = new Set<string>();  let match: RegExpExecArray | null;  let index = 0;  while ((match = re.exec(html)) !== null && blocks.length < MAX_BLOCKS) {    const raw = match[1].trim();    try {      const data: unknown = JSON.parse(raw);      const types = new Set<string>();      collectTypes(data, types);      for (const t of types) allTypes.add(t);      blocks.push({        index,        types: [...types],        data,      });    } catch (e) {      blocks.push({        index,        types: [],        data: null,        parseError: e instanceof Error ? e.message : "Invalid JSON",      });    }    index += 1;  }  return {    url,    count: blocks.length,    types: [...allTypes].sort(),    blocks,  };}

Deployment

Click the deploy button

Deploy to Cloudflare Workers

Deploy

Follow the deployment wizard. No bindings or secrets required.

Test your deployment

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

Local Development

cd apps/experiments/json-ld-extractor
npm install
npm run dev

Test locally:

curl "http://localhost:8787/extract?url=https://www.cloudflare.com"

Cloudflare Features Used

Next Steps

On this page