Hostname routing
You can use dynamic dispatch Workers to route millions of vanity domains or subdomains to Workers without hitting traditional route limits. 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.
Configure a wildcard Route (*/*
) on your SaaS domain (the domain where you configure custom hostnames) to point to your dynamic dispatch Worker. This allows you to:
- Support both subdomains and vanity domains: Handle
customer1.myplatform.com
(subdomain) andshop.customer.com
(custom hostname) with the same routing logic. - Avoid route limits: Instead of creating individual routes for every domain, which can cause you to hit Routes limits, you can handle the routing logic in code and proxy millions of domains to individual Workers.
- Programmatically control routing logic: Write custom code to route requests based on hostname, custom metadata, path, or any other properties.
If you'd like to exclude certain hostnames from routing to the dispatch Worker, you can either:
- 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) - Use a dedicated domain (for example,
customers.saas.com
) for custom hostname and dispatch worker management to keep the rest of the traffic for that domain separate.
To set up hostname routing with a wildcard route:
- Configure custom hostnames: Set up your domain and custom hostnames using Cloudflare for SaaS
- Set the fallback origin: Set up a fallback origin server, 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. 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
). - Configure DNS: Point DNS records (subdomains or custom hostname) via CNAME record to the saas domain. If your customers need to proxy their apex hostname (e.g.
example.com
) and cannot use CNAME records, check out Apex Proxying. - Create wildcard route: Add a
*/*
route on your platform domain (e.g. saas.com) and associate it with your dispatch Worker. - Implement dispatch logic: Add logic to your dispatch Worker to route based on hostname, lookup mappings stored in [Workers KV](Workers KV), or use custom metadata attached to custom hostnames.
export default { async fetch(request, env) { const hostname = new URL(request.url).hostname;
// Get custom hostname metadata for routing decisions const hostnameData = await env.KV.get(`hostname:${hostname}`, { type: 'json' });
if (!hostnameData?.workerName) { return new Response('Hostname not configured', { status: 404 }); }
// Route to the appropriate user Worker const userWorker = env.DISPATCHER.get(hostnameData.workerName); return await userWorker.fetch(request); }};
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.
To set up subdomain routing:
- 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
). - Set wildcard route:
*.saas.com/*
pointing to your dispatch Worker - Add logic to the dispatch Worker to route subdomain requests to the right Worker.
export default { async fetch(request, env) { const url = new URL(request.url); const subdomain = url.hostname.split('.')[0];
// Route based on subdomain if (subdomain && subdomain !== 'saas') { const userWorker = env.DISPATCHER.get(subdomain); return await userWorker.fetch(request); }
return new Response('Invalid subdomain', { status: 400 }); }};
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
This can cause inconsistent behavior when using specific hostname routes:
- 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. - 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.
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.
The table below shows when Workers are invoked based on your route pattern and the customer's DNS proxy settings:
Route Pattern | Custom Hostname (Orange Cloud) | Custom Hostname (Grey Cloud) |
---|---|---|
*/* (Recommended) | ✅ | ✅ |
Target hostname route | ✅ | ❌ |
Custom hostname route | ❌ | ✅ |
Was this helpful?
- Resources
- API
- New to Cloudflare?
- Products
- Sponsorships
- Open Source
- Support
- Help Center
- System Status
- Compliance
- GDPR
- Company
- cloudflare.com
- Our team
- Careers
- 2025 Cloudflare, Inc.
- Privacy Policy
- Terms of Use
- Report Security Issues
- Trademark