Origins & routing
Pick the canonical host, name the two origins, and decide which paths go where. First match wins — order matters.
Name your hosts
- Canonical host: the one your users and Google see. e.g.
www.example.com. - Primary origin: serves most traffic. e.g.
brand.webflow.io. - Secondary origin: serves a subset, usually by path prefix. e.g.
legacy.example.com.
Routing rules
A rule is just { prefix, to }. The Worker walks the list in order and uses the
first one whose prefix matches the request path. Put the most specific rules first;
end with a catch-all "/" to the primary.
const RULES = [
{ prefix: '/blog', to: 'secondary' }, // legacy WordPress blog
{ prefix: '/shop', to: 'secondary' }, // legacy storefront
{ prefix: '/', to: 'primary' }, // everything else → Webflow
]; Try it: which origin handles this request?
Edit the config, then enter a request URL to see what the Worker would do. Nothing is sent over the network — this is a faithful reimplementation of the same rules in the browser.
Path rules (first match wins)
The Worker so far
// src/index.js
const PRIMARY = 'brand.webflow.io';
const SECONDARY = 'legacy.example.com';
const RULES = [
{ prefix: '/blog', to: SECONDARY },
{ prefix: '/shop', to: SECONDARY },
{ prefix: '/', to: PRIMARY },
];
export default {
async fetch(request) {
const url = new URL(request.url);
const rule = RULES.find(r => url.pathname.startsWith(r.prefix));
if (!rule) return new Response('Not Found', { status: 404 });
const upstream = `https://${rule.to}${url.pathname}${url.search}`;
return fetch(upstream, request);
},
};
This works — but the response still references the upstream host. Open the legacy
page and you'll find
<link rel="canonical" href="https://legacy.example.com/blog/x">.
Google will index that URL, not yours. Fix it in the next step.