carlos-ai:
/*
What happens after that asterix *
, it matches anything and would route/direct as defined in your wrangler config file.
carlos-ai:
/page1
There’s invisible ending slash /
in URL address such as /page1/
.
May I ask if you’ve tried configuring Workers Route via Dashboard if it’s only few URLs or pages that need to be done?
Regarding Workers, in your Worker code for the particular sub-domain or URL, you could do search and match if URL matches xyz pattern, then 301 redirect to the desired URL.
I guess there are few ways, just be careful if you’ll get a lot of requests, you might have to switch to a Paid version of Workers.
You could also serve static files from Worker e.g. on /api/
, then serve the Website content HTML from Pages on /page1
.
Is it dynamic URLs or?
When deploying your Cloudflare Workers, you can configure which Worker handles which URL path, e.g.:
Route 1: subdomain.example.com/page1*
→ Worker 1
Route 2: subdomain.example.com/page2*
→ Worker 2
Using Pages, you can configure and use subdomain.example.com/page1/test-directory/index.html , etc. if so?
Last but not least, are you sure you’re handling correct pattern, since Page1
(uppercase) and page1
(lowercase) isn’t the same?
I don’t know what’s your logic in your Workers, however the routing can be done and you can response with HTML via Worker as well.
Example:
// Single Worker with Path-Based Routing
export default {
async fetch(request, env, ctx) {
const url = new URL(request.url);
const pathname = url.pathname;
// Route to different handlers based on path
if (pathname.startsWith('/page1')) {
return handlePage1(request, env, ctx);
} else if (pathname.startsWith('/page2')) {
return handlePage2(request, env, ctx);
} else if (pathname.startsWith('/api')) {
return handleAPI(request, env, ctx);
} else {
return handleDefault(request, env, ctx);
}
}
};
// Handler for /page1/* routes
async function handlePage1(request, env, ctx) {
const url = new URL(request.url);
// You can serve static assets or dynamic content
return new Response(`
<!DOCTYPE html>
<html>
<head><title>Page 1</title></head>
<body>
<h1>Welcome to Page 1</h1>
<p>Current path: ${url.pathname}</p>
<p>Query params: ${url.search}</p>
</body>
</html>
`, {
headers: { 'Content-Type': 'text/html' }
});
}
// Handler for /page2/* routes
async function handlePage2(request, env, ctx) {
const url = new URL(request.url);
return new Response(`
<!DOCTYPE html>
<html>
<head><title>Page 2</title></head>
<body>
<h1>Welcome to Page 2</h1>
<p>Current path: ${url.pathname}</p>
<p>Method: ${request.method}</p>
</body>
</html>
`, {
headers: { 'Content-Type': 'text/html' }
});
}
// Handler for API routes
async function handleAPI(request, env, ctx) {
const url = new URL(request.url);
return new Response(JSON.stringify({
message: "API endpoint",
path: url.pathname,
timestamp: new Date().toISOString()
}), {
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*'
}
});
}
// Default handler for root and unmatched routes
async function handleDefault(request, env, ctx) {
return new Response(`
<!DOCTYPE html>
<html>
<head><title>Main Site</title></head>
<body>
<h1>Welcome to Main Site</h1>
<nav>
<ul>
<li><a href="/page1">Go to Page 1</a></li>
<li><a href="/page2">Go to Page 2</a></li>
<li><a href="/api/test">Test API</a></li>
</ul>
</nav>
</body>
</html>
`, {
headers: { 'Content-Type': 'text/html' }
});
}
And then wrangler should be like:
name = "example-project"
compatibility_date = "2025-06-17"
main = "src/index.js"
# Route configuration
[[routes]]
pattern = "subdomain.example.com/*"
zone_name = "example.com"
# Environment variables (optional)
[vars]
ENVIRONMENT = "production"
# KV namespaces (if needed)
# [[kv_namespaces]]
# binding = "MY_KV"
# id = "your-kv-namespace-id"
Maybe it might be easier for you if you use Cloudflare Pages with Functions on the specific path
instead for such case?
E.g.:
my-project/
├── public/
│ ├── index.html
│ ├── page1/
│ │ └── index.html
│ └── page2/
│ └── index.html
├── functions/
│ ├── page1/
│ │ └── [[path]].js
│ ├── page2/
│ │ └── [[path]].js
│ └── api/
│ └── [[path]].js
└── wrangler.toml
Wrangler in such scenario:
name = "my-pages-project"
compatibility_date = "2025-06-17"
pages_build_output_dir = "public"
[build]
command = "npm run build"
cwd = "."
[[pages.rules]]
pattern = "/page1/*"
function = "page1-handler"
[[pages.rules]]
pattern = "/page2/*"
function = "page2-handler"
E.g. for /page1/path.js
:
export async function onRequest(context) {
const { request, env, params } = context;
const url = new URL(request.url);
// Handle dynamic routing for page1
return new Response(`
<h1>Page 1 Dynamic Handler</h1>
<p>Path: ${url.pathname}</p>
<p>Params: ${JSON.stringify(params)}</p>
`, {
headers: { 'Content-Type': 'text/html' }
});
}