The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →To route subdomains in Cloudflare Pages, first configure each hostname to reach the Pages project, then use a root-level functions/_middleware.js to inspect the incoming hostname and apply your application’s behavior. Pages’ built-in routing selects Functions by URL path; mapping a hostname to a site or tenant is application logic.
What subdomain routing means in Pages
There are two separate routing decisions. DNS and custom-domain configuration get a hostname such as docs.example.com to your Pages project. Middleware can then inspect that request’s hostname and choose application behavior. Separately, Pages’ standard /functions system maps URL paths to files in the Functions directory; that file-based mapping does not define which tenant or site a subdomain represents. See Cloudflare’s Functions routing documentation.
As an Amazon Associate I earn from qualifying purchases.
Configure the hostname to reach the project
Add the hostname as a custom domain for the Pages project and configure DNS so requests reach that project. Cloudflare’s custom domains documentation describes the configuration. If your nameservers are not pointed to Cloudflare, its instructions describe creating a custom CNAME record for the subdomain. A middleware hostname check cannot compensate for a hostname that does not resolve to the project.
Recommended Free Tools
Add middleware to inspect the hostname
Use a root-level functions/_middleware.js when the hostname check should apply across the project, including requests for static files. Cloudflare documents middleware as reusable logic that runs before onRequest Functions. Middleware placed in a subdirectory has narrower scope: it applies to matching Functions in that directory and its descendants. See Cloudflare’s middleware documentation.
#1 Best Overall
The following is an illustrative pattern, not a tested, universal tenant implementation:
export async function onRequest(context) {
const url = new URL(context.request.url);
const hostname = url.hostname.toLowerCase();
// Map only hostnames configured for this application.
// Decide explicitly how unknown hosts should behave.
if (hostname === "docs.example.com") {
// Apply the docs site behavior.
}
return context.next();
}
context.request is the incoming request. Calling context.next() passes it to another applicable Function or to the asset server when no other Function applies. Cloudflare documents that interface, but it does not prescribe a universal host-to-tenant lookup, unknown-host response, or security policy; those choices belong to your application. See the Pages Functions API reference.
Rank #2
Make hostname selection explicit and safe
Do not treat an arbitrary hostname as a trusted tenant identifier. Match against an allowlist of hostnames configured for your application, or use a lookup that rejects unknown hostnames and maps only approved names to tenant records. If a host selects tenant data, ensure the lookup cannot let an unrecognized or manipulated hostname select unintended data. Decide what to do when there is no match: return an intentional error or default response, or continue with context.next() if serving the normal Pages response is appropriate.
Check which requests invoke Functions
Review the project’s generated or framework-produced _routes.json to confirm which URL paths invoke Functions. Pages’ default behavior invokes Functions when they exist, while route configuration can include and exclude paths; exclusions take priority over inclusions. This affects whether middleware runs for a request, even when it is at the project root. See Cloudflare’s routing documentation.
Choose between the Functions system and advanced mode
For most projects already using Pages Functions, root middleware keeps hostname checks alongside path-based Functions and lets the request continue to another Function or the asset server. Use advanced mode when the application needs Worker-level control over incoming requests instead of the built-in routing system.
| Approach | Routing control | Functions and middleware | Static assets |
|---|---|---|---|
/functions with _middleware.js |
File-based path routes, with hostname checks added as application logic. | Uses Pages Functions and middleware. | context.next() can continue to another Function or the asset server; invocation scope depends on _routes.json. |
Advanced mode with _worker.js |
The Worker controls incoming requests. | The /functions routing system, including its middleware, is ignored. |
The Worker can serve assets through the ASSETS binding, for example with env.ASSETS.fetch(). |
In advanced mode, you are responsible for the Worker’s routing and preserving static-asset behavior where needed. Cloudflare explains the trade-off in its advanced mode documentation.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Repair Windows errors before they cause bigger problems3Fix the driver behind crashes, sound loss and screen glitches




