Skip to content

Commit 3db7a18

Browse files
authored
Add hostname routing page (#23361)
* Add hostname routing documentation for Workers for Platforms * Fix broken links in hostname routing page * Update hostname-routing.mdx
1 parent 97a32ac commit 3db7a18

File tree

1 file changed

+112
-0
lines changed

1 file changed

+112
-0
lines changed
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
---
2+
pcx_content_type: how-to
3+
title: Hostname routing
4+
description: Learn how to route requests to the dispatch worker.
5+
sidebar:
6+
order: 3
7+
---
8+
9+
import { Render, PackageManagers, WranglerConfig } from "~/components";
10+
11+
You can use [dynamic dispatch](/cloudflare-for-platforms/workers-for-platforms/get-started/dynamic-dispatch/) Workers to route millions of vanity domains or subdomains to Workers without hitting traditional [route limits](/workers/platform/limits/#number-of-routes-per-zone). These hostnames can be subdomains under your managed domain (e.g. `customer1.saas.com`) or vanity domains controlled by your end customers (e.g. `mystore.com`), which can be managed through [custom hostnames](/cloudflare-for-platforms/cloudflare-for-saas/domain-support/).
12+
13+
## (Recommended) Wildcard route with a dispatch Worker
14+
15+
Configure a wildcard [Route](/workers/configuration/routing/routes/) (`*/*`) on your SaaS domain (the domain where you configure custom hostnames) to point to your dynamic dispatch Worker. This allows you to:
16+
- **Support both subdomains and vanity domains**: Handle `customer1.myplatform.com` (subdomain) and `shop.customer.com` (custom hostname) with the same routing logic.
17+
- **Avoid route limits**: Instead of creating individual routes for every domain, which can cause you to hit [Routes limits](/workers/platform/limits/#number-of-routes-per-zone), you can handle the routing logic in code and proxy millions of domains to individual Workers.
18+
- **Programmatically control routing logic**: Write custom code to route requests based on hostname, [custom metadata](/cloudflare-for-platforms/cloudflare-for-saas/domain-support/custom-metadata/), path, or any other properties.
19+
20+
:::note
21+
This will route all traffic inbound to the domain to the dispatch Worker.
22+
:::
23+
24+
If you'd like to exclude certain hostnames from routing to the dispatch Worker, you can either:
25+
- Add routes without a Worker specification to opt certain hostnames or paths from being executed by the dispatcher Worker (for example, for `saas.com`, `api.saas.com`, etc)
26+
- Use a [dedicated domain](/dns/zone-setups/subdomain-setup/) (for example, `customers.saas.com`) for custom hostname and dispatch worker management to keep the rest of the traffic for that domain separate.
27+
28+
### Setup
29+
30+
To set up hostname routing with a wildcard route:
31+
32+
1. **Configure custom hostnames**: Set up your domain and custom hostnames using [Cloudflare for SaaS](/cloudflare-for-platforms/cloudflare-for-saas/)
33+
2. **Set the fallback origin**: Set up a [fallback origin server](/cloudflare-for-platforms/cloudflare-for-saas/start/getting-started/#1-create-fallback-origin), this is where all custom hostnames will be routed to. If you’d like to route them to separate origins, you can use a [custom origin server](/cloudflare-for-platforms/cloudflare-for-saas/start/advanced-settings/custom-origin/). Requests will route through the Worker before reaching the origin. If the Worker is the origin then place a dummy DNS record for the fallback origin (e.g., `A 192.0.2.0`).
34+
3. **Configure DNS**: Point DNS records (subdomains or custom hostname) via [CNAME record to the saas domain](/cloudflare-for-platforms/cloudflare-for-saas/start/getting-started/#3-have-customer-create-cname-record). If your customers need to proxy their apex hostname (e.g. `example.com`) and cannot use CNAME records, check out [Apex Proxying](/cloudflare-for-platforms/cloudflare-for-saas/start/advanced-settings/apex-proxying/).
35+
4. **Create wildcard route**: Add a `*/*` route on your platform domain (e.g. saas.com) and associate it with your dispatch Worker.
36+
5. **Implement dispatch logic**: Add logic to your dispatch Worker to route based on hostname, lookup mappings stored in [Workers KV]([Workers KV](/kv/)), or use [custom metadata](/cloudflare-for-platforms/cloudflare-for-saas/domain-support/custom-metadata/) attached to custom hostnames.
37+
38+
:::note
39+
If you plan to route requests based on custom metadata, you'll need to create subdomains (e.g. `customer1.saas.com`) as custom hostnames. This is because DNS records do not support custom metadata.
40+
:::
41+
42+
#### Example dispatch Worker
43+
44+
```js
45+
export default {
46+
async fetch(request, env) {
47+
const hostname = new URL(request.url).hostname;
48+
49+
// Get custom hostname metadata for routing decisions
50+
const hostnameData = await env.KV.get(`hostname:${hostname}`, { type: 'json' });
51+
52+
if (!hostnameData?.workerName) {
53+
return new Response('Hostname not configured', { status: 404 });
54+
}
55+
56+
// Route to the appropriate user Worker
57+
const userWorker = env.DISPATCHER.get(hostnameData.workerName);
58+
return await userWorker.fetch(request);
59+
}
60+
};
61+
```
62+
63+
## Subdomain routing
64+
65+
If you're only looking to route subdomain records (e.g. `customer1.saas.com`), you can use a more specific route (`*.saas.com/*`) to route requests to your dispatch Worker.
66+
67+
### Setup
68+
69+
To set up subdomain routing:
70+
71+
1. Create an orange-clouded wildcard DNS record: `*.saas.com` that points to the origin. If the Worker is the origin then you can use a dummy DNS value (for example, `A 192.0.2.0`).
72+
2. Set wildcard route: `*.saas.com/*` pointing to your dispatch Worker
73+
3. Add logic to the dispatch Worker to route subdomain requests to the right Worker.
74+
75+
#### Example subdomain dispatch Worker
76+
77+
```js
78+
export default {
79+
async fetch(request, env) {
80+
const url = new URL(request.url);
81+
const subdomain = url.hostname.split('.')[0];
82+
83+
// Route based on subdomain
84+
if (subdomain && subdomain !== 'saas') {
85+
const userWorker = env.DISPATCHER.get(subdomain);
86+
return await userWorker.fetch(request);
87+
}
88+
89+
return new Response('Invalid subdomain', { status: 400 });
90+
}
91+
};
92+
```
93+
94+
### Orange-to-Orange (o2o) Behavior
95+
96+
When your customers are also using Cloudflare and point their custom domain to your SaaS domain via CNAME (for example, `mystore.com` → `saas.com`), Worker routing behavior depends on whether the customer's DNS record is proxied (orange cloud) or DNS-only (grey cloud). Learn more about [Orange-to-Orange setups](/cloudflare-for-platforms/cloudflare-for-saas/saas-customers/how-it-works/#with-o2o)
97+
98+
This can cause inconsistent behavior when using specific hostname routes:
99+
- If you're routing based on the CNAME target (`saas.com`), the custom hostname's DNS record must be orange-clouded for the Worker to be invoked.
100+
- If you're routing based on the custom hostname (`mystore.com`), the customer's record must be grey-clouded for the Worker to be invoked.
101+
102+
Since you may not have control over your customer's DNS proxy settings, we recommend using `*/*` wildcard route to ensure routing logic always works as expected, regardless of how DNS is configured.
103+
104+
#### Worker invocation across route configurations and proxy modes
105+
106+
The table below shows when Workers are invoked based on your route pattern and the customer's DNS proxy settings:
107+
108+
| Route Pattern | Custom Hostname (Orange Cloud) | Custom Hostname (Grey Cloud) |
109+
|-----------------------|--------------|------------|
110+
| `*/*` (Recommended) | ✅ | ✅ |
111+
| Target hostname route | ✅ | ❌ |
112+
| Custom hostname route | ❌ | ✅ |

0 commit comments

Comments
 (0)