Self-Hosted Middleware: Prerender Without Changing Your DNS
Most Hado SEO setups point your DNS at our proxy. If you’d rather keep your own infrastructure — your CDN, your Worker, your routing — you can run a thin Cloudflare Worker in front of your site that pre-filters bot traffic and calls the Hado SEO render endpoint for prerendered HTML.Advanced / self-hosted. This guide is for teams that want to integrate at
the edge themselves. If you just want SEO with zero code, use the
DNS setup instead.
How it works
Your Worker is a thin, untrusted client. All the heavy lifting — authentication, domain authorization, authoritative bot verification, caching, and rendering — lives in the Hado SEO service. Your Worker only has to:- Decide if a request looks like a bot (a cheap User-Agent check).
- For bots, ask the Hado SEO render endpoint for prerendered HTML.
- Serve that HTML on
200, or serve your app normally on204(passthrough).
Your bot check can be loose. Hado SEO re-verifies every bot authoritatively
(User-Agent + published IP ranges), so a human or spoofed crawler that slips
through simply gets a
204 and is served your normal app. False positives only
cost one subrequest.Prerequisites
- Your site’s domain is on Cloudflare (the zone is active and serving your traffic) — the Worker runs on your zone, in front of your existing app.
- Node 18+ locally, for the
wranglerCLI. (Everything below can also be done in the Cloudflare dashboard UI; the CLI path is shown because it’s exactly reproducible.)
Setup
1
Add your domain in Hado SEO
Sign up at hadoseo.com/auth. In onboarding,
when asked “How are you connecting?”, choose Cloudflare Worker.
Enter your custom domain — that’s all; unlike the DNS path, no app URL is
needed. This registers domain ownership: the render endpoint only
serves domains your account owns.
2
Copy your API key
The onboarding success screen issues an API key (
hado_sk_...) and shows
it once — copy it now. If you already closed it, create a new key in
Settings → API Keys. See Authentication.3
Copy your render endpoint
From the same screen (or the dashboard’s domain page):
4
Create the Worker project
The fastest path is cloning the ready-made template — Worker, config, and
deploy scripts included:Or build it by hand — a fresh directory with three files is all it takes:Save the Worker below as Replace
src/worker.js, and add:wrangler.toml
example.com with your domain in both patterns and zone_name.5
Set your API key as a secret
[vars] entry — vars are visible in the
dashboard and in wrangler.toml.6
Deploy
7
Verify
Three checks, in order:
- Open your Hado SEO dashboard → Analytics: the test crawls appear within a few minutes. Then run the SEO Bot Crawler Test against a page to confirm real crawlers receive fully rendered HTML.
The Worker
This is the samesrc/worker.js shipped in the
hado-cloudflare-worker template —
clone that instead of copy-pasting if you want the wrangler config and deploy
scripts along with it.
src/worker.js
What the Worker sends
GET {HADO_RENDER_ENDPOINT}?url=<absolute request URL> with:
The Worker also fires a fire-and-forget
POST {HADO_RENDER_ENDPOINT origin}/v1/event/referral
beacon for human page navigations that carry a Referer, with body
{"url": "<landing URL>", "referer": "<referer>"} and the same auth. This is
how visits arriving from AI assistants (ChatGPT, Perplexity, Claude, …) show up
in your AI-referral analytics — no IP is ever sent on this path. It always
returns 204; failures are silently ignored and never affect the visitor.
How to handle the response
The service fails open: on any internal error or timeout it returns
204
rather than a 5xx, so your site never breaks. Your Worker should mirror that —
fall through to fetch(request) on anything that isn’t a 200, a 404
snapshot, or a redirect.
Routing rules & blocked paths. Redirect rules from your dashboard are
returned as real
30x responses so bots see them. Proxy rules and blocked
paths come back as 204 — your own edge serves those paths (Hado never
prerenders them), and blocked-path robots directives arrive in
x-hadoseo-robots for you to forward. Rule changes take effect within about
a minute (the service caches your domain config briefly).Redirects for human visitors
The Worker only routes bot traffic through Hado SEO, so your dashboard’s redirect rules apply to crawlers — which is what consolidates link equity and keeps search engines pointed at the right URLs. Human visitors go straight to your app, untouched, and that’s deliberate: it keeps the Worker from adding any latency to real users. For humans, configure the same redirects where they’re free and instant on your own zone: Cloudflare Redirect Rules (or Bulk Redirects for long lists) under Rules in your Cloudflare dashboard, or in your app’s own routing. When you move a page, set the redirect in both places — your zone rule covers visitors, your Hado rule guarantees crawlers see the301 even
before caches turn over.
Analytics-only (passthrough mode)
Only want crawl and AI-agent analytics, without serving prerendered HTML? Send thex-hadoseo-mode: passthrough header on every request. Hado SEO records who
crawled what (feeding your crawl analytics) and returns
204, so your app is always served as-is.
Caching repeat bot hits (optional)
Every200 comes back with Cache-Control: public, s-maxage=… , stale-while-revalidate=….
If you serve the Worker response from Cloudflare’s cache, repeat bot hits for the
same URL are served from your edge and never reach Hado SEO. The simplest approach
is to store the render in the Worker’s caches.default, keyed by the request URL,
and revalidate in the background with ctx.waitUntil.
How Hado SEO Works
Understand caching, bot verification, and the render pipeline behind the endpoint.