
Short answer: To use Cloudflare Workers for SEO, put a small script on your domain’s route that changes requests or HTML before they reach the browser. The safest uses are redirects, canonical and hreflang tags, robots and security headers, and fixing titles or meta descriptions a platform will not let you edit. Serve the same content to users and Googlebot, test on a staging route, and keep a rollback ready.
This guide is for SEOs and site owners who are stuck on a platform, theme or development queue that will not let them make basic technical fixes. I will show you which SEO jobs belong at the edge and which do not, the working code I start from, how to stay on the right side of Google’s cloaking rules, and the deployment checklist I use so a Worker never takes a site down. You need a site that already uses Cloudflare for DNS and some comfort reading JavaScript.
What a Cloudflare Worker does for SEO
A Worker is a piece of JavaScript that runs on Cloudflare’s network between the visitor and your server (the origin). When a request for example.com/page/ arrives, the Worker can answer it directly (for example with a 301), pass it to the origin unchanged, or fetch the page from the origin and edit the HTML or headers on the way back. Nothing on the origin changes, which is the whole point. This approach is usually called edge SEO.
For SEO, the useful part is the HTML editing. Cloudflare’s HTMLRewriter API parses the page as it streams through, so you can target elements with CSS selectors and set attributes, append tags to the <head>, or remove elements without buffering the whole document. That matters for speed, because a careless Worker that reads the full page into memory and runs string replacements on it adds delay to every request.
When the edge is the right place for a fix
When I audit a site, I only reach for a Worker when the proper fix is blocked. Edge logic is another layer someone has to remember, and the next developer may never know it exists. Use this table to decide.
| Situation | Fix at the edge? | Why |
|---|---|---|
| Hosted platform will not allow server redirects (some SaaS shops, site builders, GitHub Pages) | Yes | A Worker returns a true 301 instead of a JavaScript or meta refresh redirect |
| Migration with thousands of old URLs and a slow dev queue | Yes, temporarily | Edge redirect map goes live on launch day; move it to the server later |
| Missing or wrong canonical or hreflang tags in a theme you cannot edit | Yes | HTMLRewriter can set them per URL from a lookup table |
| Security headers, X-Robots-Tag on PDFs or staging subdomains | Yes | Header changes are cheap and easy to verify |
| Rewriting body copy or adding large blocks of text | Rarely | Content belongs in the CMS where editors can see and maintain it |
| You control the server and the CMS | No | Make the change at the source; it is simpler to maintain and debug |
| Showing different content to Googlebot than to users | Never | That is cloaking under Google’s spam policies |
Rather have an expert do this for you?
Hand it over and get back to running your business.
Setting up your first SEO Worker
- Confirm the site is proxied. The DNS record for your domain must show the orange cloud in Cloudflare. A Worker cannot run on DNS-only records.
- Create the Worker. In the dashboard go to Workers and Pages, create a Worker, or use Cloudflare’s Wrangler command-line tool if you want the code in version control (I recommend this for anything beyond a test).
- Attach a route. Start with a narrow route on a staging host or a single path, such as
staging.example.com/*orexample.com/test-folder/*, before you put it on the whole site. - Set the failure mode. Choose “fail open” where the option exists, so if the Worker errors or hits its limit, requests go straight to the origin rather than returning an error page.
- Test, then widen the route. Check status codes, headers and rendered HTML (details below), then move the route to
example.com/*.
On cost: Cloudflare’s Workers pricing page lists 100,000 requests a day on the free plan and a $5 monthly paid plan that includes 10 million requests. A Worker on example.com/* runs on every request, including images and scripts, so a busy site can pass the free limit quickly. Either upgrade or scope the route to HTML paths.
Five SEO jobs with working code
These examples use the current module syntax. Each is a starting point, not something to paste into production without testing.
1. Redirects from a lookup map
Keep redirects as data, not as a long chain of if statements. For a few hundred URLs an object in the script is fine; for thousands, store the map in Workers KV.
Code: 301 redirects from a map
const REDIRECTS = {
"/old-services/": "/services/",
"/blog/seo-tips-2019/": "/blog/seo-tips/",
"/shop/red-kurta": "/shop/kurtas/red-lawn-kurta/"
};
export default {
async fetch(request) {
const url = new URL(request.url);
const target = REDIRECTS[url.pathname];
if (target) {
return Response.redirect(url.origin + target + url.search, 301);
}
return fetch(request);
}
};It keeps the query string, which preserves UTM tags, and returns a proper 301. Check each destination returns 200 so you do not create chains.
After launch, run a sample of old URLs through my redirect checker to confirm one hop and a 301 status. For the wider process, see my website migration SEO checklist.
2. Canonical and hreflang tags with HTMLRewriter
This is the job I use Workers for most: a platform outputs the wrong canonical or none at all, and the theme is locked. HTMLRewriter removes the existing tag and writes the right one.
Code: set a canonical and hreflang alternates
const HREFLANG = {
"/pricing/": [
["en-gb", "https://example.com/pricing/"],
["en-ae", "https://example.com/ae/pricing/"],
["x-default", "https://example.com/pricing/"]
]
};
export default {
async fetch(request) {
const response = await fetch(request);
const type = response.headers.get("content-type") || "";
if (!type.includes("text/html")) return response;
const url = new URL(request.url);
const canonical = url.origin + url.pathname;
const alternates = HREFLANG[url.pathname] || [];
return new HTMLRewriter()
.on('link[rel="canonical"]', { element(el) { el.remove(); } })
.on("head", {
element(el) {
el.append('<link rel="canonical" href="' + canonical + '">', { html: true });
for (const [lang, href] of alternates) {
el.append('<link rel="alternate" hreflang="' + lang + '" href="' + href + '">', { html: true });
}
}
})
.transform(response);
}
};The content-type check stops the Worker touching images and scripts. The canonical here drops query strings; adjust that if parameters create genuinely different pages. Every hreflang set must be reciprocal across the alternates.
If you are new to the tag itself, read my guide to the hreflang tag first; most hreflang problems I see are logic errors, not delivery problems.
3. Robots and security headers
Headers are the lowest-risk edge change. Typical uses: X-Robots-Tag: noindex on a staging host or on PDFs you do not want indexed, and security headers such as Strict-Transport-Security.
Code: add X-Robots-Tag to PDFs and a staging host
export default {
async fetch(request) {
const url = new URL(request.url);
const response = await fetch(request);
const headers = new Headers(response.headers);
if (url.hostname.startsWith("staging.") || url.pathname.endsWith(".pdf")) {
headers.set("X-Robots-Tag", "noindex");
}
headers.set("Strict-Transport-Security", "max-age=31536000");
return new Response(response.body, { status: response.status, headers });
}
};Confirm the result with my HTTP header checker. Remember that a noindex header only works if the URL is not blocked in robots.txt, because Google has to fetch the page to see it.
4. Titles and meta descriptions on locked templates
Some platforms generate titles like “Products | Store” for every category. HTMLRewriter can set the <title> text and the description from a per-URL table. Use this as a bridge until the platform is fixed, and follow the same rules as any meta tag optimisation: unique, accurate and written for the searcher.
5. Logging crawler requests
If your host does not give you raw access logs, a Worker can send a copy of each request from search engine and AI crawlers to a logging endpoint, which gives you the data for log file analysis. Do not trust the user-agent alone: anyone can claim to be Googlebot. Google’s crawler verification guide explains the reverse and forward DNS check and the published IP range files.
Staying clear of cloaking
Workers make it trivially easy to check the user-agent and serve Googlebot something different. Do not. Google’s spam policies define cloaking as presenting different content to users and search engines with the intent to manipulate rankings and mislead users. My rule is simple: every edge change must be applied to every visitor. Status codes, tags and headers should be identical whether the request comes from Chrome in Karachi or Googlebot in the US.
Two grey areas I get asked about. Location-based content (prices in PKR for Pakistani visitors, AED for the UAE) is fine for users but remember Googlebot mostly crawls from the US, so it will only see one version; separate URLs with hreflang are safer than swapping content on one URL. Blocking abusive bots is also fine, but verify crawlers by IP before you block anything that claims to be a search engine.
Testing and rolling out safely
A broken Worker on a site-wide route is a site-wide outage. Before you widen any route:
Edge SEO deployment checklist
- Write down the reason: what the Worker changes, why it cannot be fixed at the origin, and who owns it.
- Keep the code in version control: deploy with Wrangler so every change has a history and can be rolled back.
- Test on a staging host or narrow path first: never on
example.com/*straight away. - Skip non-HTML responses: check the content-type before running HTMLRewriter.
- Check status codes: redirects return 301 in one hop; normal pages still return 200.
- View the raw HTML, not the DOM: use view-source or curl to confirm tags are in the served HTML.
- Run URL Inspection in Search Console: confirm Google’s rendered HTML shows the new canonical or hreflang.
- Compare response times: measure TTFB before and after on several pages.
- Watch request volume: make sure the route will not exceed your plan’s limits.
- Set fail open where available: errors should fall through to the origin.
- Document it where developers will see it: a note in the repository and the CMS so nobody fights the Worker later.
- Review quarterly: move permanent fixes to the origin when you can and delete dead rules.
Ticks are saved in your browser, so you can work through this during a deployment.
Mistakes I see with SEO Workers
- Running string replace on the whole HTML. It buffers every page and breaks the moment the theme changes a space. HTMLRewriter is faster and more reliable.
- Two sources of truth. The CMS outputs one canonical and the Worker adds a second. Always remove the old tag before adding a new one.
- Edge redirects pointing at redirects. When the server later adds its own redirects, chains appear. Recheck after every release.
- Forgetting the Worker exists. Months later a developer cannot work out why their change is not showing. Documentation solves this.
- Expecting rankings from speed alone. Caching at the edge can help Core Web Vitals, but Cloudflare’s normal caching usually does that without custom code.
Frequently asked questions
Are Cloudflare Workers good for SEO?
They are useful when you cannot change the server or CMS. They let you add redirects, canonical and hreflang tags, headers and title fixes at the network edge. They do not improve rankings on their own; they help you ship technical fixes that would otherwise wait in a queue.
Can Google see changes made by a Cloudflare Worker?
Yes. HTMLRewriter edits the HTML before it leaves Cloudflare, so Googlebot receives the modified page just like a browser does. Confirm with the URL Inspection tool in Search Console.
Is edge SEO cloaking?
Not if every visitor gets the same result. It becomes cloaking when you serve search engines different content from users to manipulate rankings, which Google’s spam policies prohibit.
How much do Cloudflare Workers cost?
Cloudflare’s free plan includes 100,000 Worker requests a day. The paid plan starts at $5 a month with 10 million requests included, with usage charges beyond that. Check Cloudflare’s pricing page for current limits before you deploy site-wide.
Do I need to be a developer to use Workers for SEO?
You need to read and adjust simple JavaScript, and you should test carefully. For anything site-wide, involve a developer or someone who can monitor and roll back the Worker.
Should I use a Worker or Cloudflare’s built-in redirect rules?
For simple, static redirects, Cloudflare’s built-in redirect rules are easier to maintain. Use a Worker when you need logic, large maps stored in KV, or HTML changes alongside the redirects.
Sources
- Cloudflare Developers, “Workers pricing” (accessed 2026).
- Cloudflare Developers, “HTMLRewriter” runtime API documentation (accessed 2026).
- Google Search Central, “Spam policies for Google web search” (accessed 2026).
- Google Search Central, “Verifying Googlebot and other Google crawlers” (accessed 2026).
If your platform is blocking technical fixes and you want a second opinion on whether the edge is the right answer, my technical SEO services cover edge implementations end to end, or you can tell me about your setup.
Request received
Thank you! Saad will contact you within the next 24 hours.
Keep an eye on your phone and inbox.
