Build a URL redirect service with Cloudflare Workers
Learn how to create a lightweight redirect endpoint using Cloudflare Workers, Wrangler, and a simple JavaScript snippet.
21 Nov 2025, 08:33 UTC

Overview
You can create a lightweight redirect endpoint that runs at Cloudflare’s edge without managing any servers. A Worker inspects the incoming request URL, decides whether to redirect, and returns a 302 Found response with a Location header pointing to the target URL. The following sections walk through a concrete example, deployment steps, limits, and common pitfalls.
Create the Worker script
Save the following JavaScript as src/index.js. It redirects any request whose path starts with /old/ to a base URL defined in an environment variable, preserving the rest of the path and the query string.
addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request))
})
async function handleRequest(request) {
const url = new URL(request.url)
const prefix = '/old/'
if (url.pathname.startsWith(prefix)) {
const base = BASE_URL || 'https://example.com'
const target = new URL(base + url.pathname.substring(prefix.length) + url.search)
// Preserve the original HTTP method (GET, POST, etc.) by issuing a 307 if needed
// For a simple GET‑only redirect, 302 is fine.
return Response.redirect(target.toString(), 302)
}
// If no match, proxy the request to the origin (optional)
return fetch(request)
}
The script uses the Fetch API event listener pattern required by Workers. event.respondWith() is mandatory; omitting it causes the request to hang.
Configure with Wrangler
Initialize a Worker project and add a wrangler.toml file that defines the environment variable.
# wrangler.toml
name = "redirect-service"
main = "src/index.js"
compatibility_date = "2024-09-01"
[vars]
BASE_URL = "https://example.com"
Run the following commands from the project directory (you need a Cloudflare account and API token with Account.Edit Workers Scripts permission):
npm init -y(optional, creates apackage.json)npm install -D wrangler(installs Wrangler locally)npx wrangler login(opens a browser to authorize)npx wrangler publish(uploads the script to your account’s.workers.devsubdomain)
After publishing, the Worker is reachable at https://<your-subdomain>.workers.dev.
Deploy and Test
Verify the redirect works with curl or a browser:
curl -i https://<your-subdomain>.workers.dev/old/test?foo=bar
Expected response (headers only shown):
HTTP/1.1 302 Found
location: https://example.com/test?foo=bar
...
Check the Workers dashboard for CPU time usage; each request should stay well below the free‑plan limit of 50 ms.
Limits and Common Mistakes
- CPU time: Free Workers receive 50 ms of CPU time per request. Complex logic (e.g., large lookup tables) can exceed this and produce a “CPU time exceeded” error. Keep the script simple or upgrade to a paid plan for higher limits.
- Script size: The bundled Worker must be under 1 MB. Large dependencies increase size; consider using the built‑in
fetchAPI instead of heavy libraries. - Missing
event.respondWith(): If you return aResponsedirectly from the fetch handler without callingevent.respondWith(), the request will hang and eventually timeout. - Incorrect URL handling: Failing to preserve the query string (
url.search) or mishandling the path can lead to broken redirects or infinite loops (e.g., redirecting/old/to/old/). Always test with a variety of inputs. - HTTP method: A 302 changes the method to GET for most browsers. If you need to preserve POST/PUT, use a 307 or 308 instead of 302.
Verification and Rollback
After deployment, verify:
- The redirect returns the expected
Locationheader. - The response status is 302 (or 307/308 if you changed it).
- No errors appear in the Workers logs.
If you need to undo the change, you can delete the Worker:
npx wrangler delete redirect-service
Or simply republish an earlier version using wrangler publish --env‑var … with the previous script.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.