Schema App – Cloudflare Worker
Inject Schema App markup into your HTML at the edge using a Cloudflare Worker. The Worker fetches markup from Schema App’s data CDN (by page URL) and injects it as <script type="application/ld+json"> before </head>, so the browser never talks to Schema App directly.
You can download the package from the following link: https://cdn.schemaapp.com/javascript/schema-app-cloudflare-worker.tar.gz
tar -xzvf schema-app-cloudflare-worker.tar.gz
cd schema-app-cloudflare-worker
Prerequisites
Node.js (v20+ LTS recommended)
Your site (or a route) proxied through Cloudflare
Schema App Account ID from Schema App → Integration → JavaScript
Setup
- Install dependencies
cd cloudflare-worker
npm install
- Set your Schema App account ID
Edit wrangler.toml and set SCHEMA_ACCOUNT_ID in the [vars] section to your Schema App account ID (e.g. the path after schemaapp.com/db/):
[vars]
SCHEMA_ACCOUNT_ID = "YourAccountId"
- Optional: environment and highlighter cache
Data environment
By default the Worker uses production (
data.schemaapp.com). For test or UAT, set a variable inwrangler.tomlunder[vars]:SCHEMA_DATA_ENV = "tst"→datatst.schemaapp.comSCHEMA_DATA_ENV = "uat"→datauat.schemaapp.com
Highlighter cache
To also inject markup from the highlighter cache (aligned with “fetch from highlight JS cache” in the JS embed), set:
SCHEMA_FETCH_HIGHLIGHTER_CACHE = "true"in[vars]
Deploy
- Log in to Cloudflare (if needed)
npx wrangler login
- Deploy the Worker
npm run deploy
Or:
npx wrangler deploy
After deployment, Wrangler prints the Worker’s URL. The Worker does nothing until you attach it to a route.
Attach the Worker to your site
In the Cloudflare dashboard, select the zone (domain) for your site.
Go to Workers Routes (or Workers & Pages → Overview → Routes).
Add a route:
Route: e.g.
*example.com/*(all paths) or*example.com/blog/*(only under/blog).Worker: choose
schema-app-markup(or the name in yourwrangler.toml).
Once the route is active, HTML responses for that route will be processed by the Worker and schema markup will be injected when available for the requested URL.
Behavior
URL for lookup: The Worker uses the request URL with query and fragment stripped (origin + pathname), matching the “strip URLs” behavior of the JavaScript embed.
HTML only: Only responses with
Content-Typeincludingtext/htmlare modified. Others are returned unchanged.Injection: Markup is inserted as
<script type="application/ld+json">…</script>immediately before</head>. If the Schema App data endpoint returns no markup or errors, the original HTML is returned unchanged.Missing config: If
SCHEMA_ACCOUNT_IDis not set (in[vars]or dashboard), the Worker forwards the request without injection.
Local development
npm run dev
Use the local URL Wrangler prints. For local testing you’ll need a way to hit your origin (e.g. --remote or a tunnel). Config is read from wrangler.toml; use .dev.vars for local overrides (do not commit .dev.vars).
Limitations
Request URL only: The Worker does not read
<link rel="canonical">from the page; it uses the request URL only.Cached markup only: This path injects markup that is already in the Schema App data cache. It does not run the highlighter or other client-side logic unless you enable
SCHEMA_FETCH_HIGHLIGHTER_CACHEand that markup exists in the cache.
Testing
Live test site (domain + Pages + Worker)
To test on a real website with no existing domain: use the minimal test-site and follow docs/LIVE-TEST-SETUP.md. That guide walks through getting a domain, adding it to Cloudflare, deploying the test-site with Cloudflare Pages, deploying the Worker, and attaching the Worker to your domain.
1. Unit tests (no deploy)
Run tests for URL normalization, base64 encoding, and HTML injection (no live fetch or Cloudflare):
cd cloudflare-worker
npm install
npm test
Requires Node 20+ (see engines in package.json). Tests live in src/index.test.ts.
2. Local dev (Worker + real origin)
- Set
SCHEMA_ACCOUNT_IDinwrangler.toml[vars], or for local overrides use a.dev.varsfile (do not commit):
SCHEMA_ACCOUNT_ID=YourAccountId
- Start the Worker:
npm run dev
The Worker runs locally but must receive requests that look like your real site. Options:
Same zone in Cloudflare: Use a route that points to a test hostname that proxies to your origin; in dev you can use
wrangler dev --remoteso the Worker runs in Cloudflare and receives real traffic (with a tunnel or test URL).Stub origin: Use a tool like
curlto send a request to the Worker URL with a Host header that matches a zone where the Worker is attached, and mock the “origin” by having the Worker fetch a known HTML URL (would require a small config change to pass an origin override for testing).
- Inspect the response: the HTML should contain
<script type="application/ld+json">before</head>when the data endpoint returns markup for that URL.
3. Deployed integration test
Deploy to a test Cloudflare zone (or a subdomain):
npm run deploy.In the dashboard, add a Workers Route so the Worker runs on that zone (e.g.
*test.example.com/*).Set SCHEMA_ACCOUNT_ID in
wrangler.toml[vars](or in the dashboard under Variables). For test data useSCHEMA_DATA_ENV = "tst"in Variables and a Schema App test account.Open a page on that host that has markup in the Schema App data cache (same URL logic as the JS embed: origin + pathname).
Verify: View source or Inspect; the
<head>should contain one or more<script type="application/ld+json">blocks. You can compare with the same URL using the JavaScript integration to confirm the same markup is injected.Optional: Run
npm run tailand load the page to see Worker logs and any errors.
Verifying the Worker is working
If the Worker appears in your invocation logs but you’re not sure it’s doing anything, use these checks:
View the response HTML
Open your page, then View Page Source (right‑click → View Page Source), or open DevTools → Network → select the document request → Response.
If the Worker is injecting and Schema App has markup for that URL, you’ll see one or more
<script type="application/ld+json">…</script>blocks inside<head>, right before</head>.If you see your normal HTML but no such scripts, the Worker is likely running but the Schema App data endpoint returned no markup for that URL (see step 3).
Use real-time logs with debug
Set a variable for the Worker:
SCHEMA_DEBUG=true(Workers & Pages → your Worker → Settings → Variables).Redeploy the Worker (
npm run deploy), then runnpm run tail(ornpx wrangler tail) in thecloudflare-workerdirectory.Load your page in the browser. In the tail output you should see one of:
[schema-app-worker] injected N script(s) for <url>— markup was found and injected.[schema-app-worker] no markup for URL (data endpoint returned none): <url>— Worker ran and asked Schema App, but there was no markup for that URL.[schema-app-worker] pass-through: ...— Worker ran but skipped (e.g. not HTML, or missing credentials).
Turn off
SCHEMA_DEBUGwhen you’re done (and redeploy) so you don’t fill logs.
Confirm Schema App has markup for that URL
The Worker looks up markup by origin + pathname (e.g.
https://yourdomain.com/orhttps://yourdomain.com/about). Query/fragment are stripped.In Schema App, ensure that URL has cached markup for your account. Quick check: put the JavaScript integration on a test page with the same URL and confirm JSON-LD appears there. If the JS embed shows no markup for that URL, the Worker will also have nothing to inject.
Troubleshooting
No markup on the page: Confirm the page URL (origin + pathname) has markup in Schema App for your account (e.g. test with the JavaScript integration on the same URL). Ensure the route is correct and the Worker is attached.
Logs: Run
npm run tail(ornpx wrangler tail) and load a page to see Worker logs and errors. EnableSCHEMA_DEBUG = true(see above) to see whether the Worker injected or passed through.
Building the customer package (maintainers)
To create a tar file for distribution to customers (e.g. for support or downloads), from the schema-scripts repo root or from cloudflare-worker:
cd cloudflare-worker
npm run pack:customer
This produces cloudflare-worker/dist/schema-app-cloudflare-worker.tar.gz. The archive contains everything needed to deploy (source, config, README, test-site, docs) and excludes node_modules, .wrangler, .dev.vars, and internal docs. Customers extract the archive, run npm install, set SCHEMA_ACCOUNT_ID in wrangler.toml, and deploy as described in this README.
Was this article helpful?
That’s Great!
Thank you for your feedback
Sorry! We couldn't be helpful
Thank you for your feedback
Feedback sent
We appreciate your effort and will try to fix the article