Routes
Background
Routes allow users to map a URL pattern to a Worker script to enable Workers to run in front of Custom Domains or their own external application servers. Customers must manually create DNS records and certificates for Routes to invoke over HTTP(S).
Customize your routes
For zones proxied on Cloudflare, route patterns decide what (if any) script is matched based on the URL of that request. Requests are routed through a Workers script when the URL matches a route pattern assigned to that script. To add a Route, you must have:
- An active Cloudflare zone.
- A valid proxied (orange-clouded) DNS record.
- A Worker to invoke.
- A certificate covering the relevant DNS record.
Route patterns can be added with the Cloudflare API or in Account Home > Workers > your Worker > Triggers > Add route in the Cloudflare dashboard.
Cloudflare Site routes are comprised of:
- Route URL (refer to Matching Behavior)
- Worker script to execute on matching requests
- Failure mode for rate-limited accounts on the Free plan (refer to daily request limits)
The Routes REST API documentation can be found in the Workers API docs.
If your route is configured to a hostname, you will need to add a DNS record to Cloudflare to ensure that the hostname can be resolved externally. If your Worker acts as your origin (that is, the request terminates in a Worker), you must add a DNS record.
- A zone that you have registered with some registrar (not workers.dev) and setup Cloudflare to serve as a reverse proxy.
Routes with *.workers.dev
Cloudflare Workers accounts come with a *.workers.dev
subdomain that is configurable in the Cloudflare dashboard. Your *.workers.dev
subdomain allows you to deploy Workers without attaching your domain as a Cloudflare zone.
To claim a *.workers.dev
subdomain, such as <YOUR_SUBDOMAIN>.workers.dev
, go to Account Home > Workers > Your subdomain. The name
field in your Worker configuration is used as the preview subdomain for the deployed script, (for example, my-worker.<YOUR_SUBDOMAIN>.workers.dev.
).
Matching Behavior
Route patterns look like this:
https://*.example.com/images/*
This pattern would match all HTTPS requests destined for a subhost of
example.com and whose paths are prefixed by /images/
.
A pattern to match all requests looks like this:
*example.com/*
While they look similar to a regex pattern, route patterns follow specific rules:
The only supported operator is the wildcard (
*
), which matches zero or more of any character.Route patterns may not contain infix wildcards or query parameters. For example, neither
example.com/*.jpg
norexample.com/?foo=*
are valid route patterns.When more than one route pattern could match a request URL, the most specific route pattern wins. For example, the pattern
www.example.com/*
would take precedence over*.example.com/*
when matching a request forhttps://www.example.com/
. The patternexample.com/hello/*
would take precedence overexample.com/*
when matching a request forexample.com/hello/world
.Route pattern matching considers the entire request URL, including the query parameter string. Since route patterns may not contain query parameters, the only way to have a route pattern match URLs with query parameters is to terminate it with a wildcard,
*
.Route patterns are case sensitive, for example,
example.com/Images/*
andexample.com/images/*
are two distinct routes.
A route can be specified without being associated with a Worker. This will act to negate any less specific patterns. For example, consider this pair of route patterns, one with a Workers script and one without:
*example.com/images/cat.png -> <no script>*example.com/images/* -> worker-script
In this example, all requests destined for example.com and whose paths are prefixed by /images/
would be routed to worker-script
, except for /images/cat.png
, which would bypass Workers completely. Requests with a path of /images/cat.png?foo=bar
would be routed to worker-script
, due to the presence of the query string.
Configure your wrangler.toml
To configure a route in your wrangler.toml
, add the following to your environment:
routes = [ { pattern = "example.com/about", zone_id = "<YOUR_ZONE_ID>" }
]
If you have specified your zone ID in the environment of your wrangler.toml
, you will not need to write it again in object form.
Validity
The following set of rules govern route pattern validity.
Route patterns must include your zone
If your zone is example.com
, then the simplest possible route pattern you can have is example.com
, which would match http://example.com/
and https://example.com/
, and nothing else. As with a URL, there is an implied path of /
if you do not specify one.
Route patterns may not contain any query parameters
For example, https://example.com/?anything
is not a valid route pattern.
Route patterns may optionally begin with http:// or https://
If you omit a scheme in your route pattern, it will match both http://
and https://
URLs. If you include http://
or https://
, it will only match HTTP or HTTPS requests, respectively.
https://*.example.com/
matcheshttps://www.example.com/
but nothttp://www.example.com/
.*.example.com/
matches bothhttps://www.example.com/
andhttp://www.example.com/
.
Hostnames may optionally begin with *
If a route pattern hostname begins with *
, then it matches the host and all subhosts. If a route pattern hostname begins with *.
, then it only matches all subhosts.
*example.com/
matcheshttps://example.com/
andhttps://www.example.com/
.*.example.com/
matcheshttps://www.example.com/
but nothttps://example.com/
.
Paths may optionally end with *
If a route pattern path ends with *
, then it matches all suffixes of that path.
https://example.com/path*
matcheshttps://example.com/path
andhttps://example.com/path2
andhttps://example.com/path/readme.txt
Subdomains must have a DNS Record
All subdomains must have a DNS record to be proxied on Cloudflare and used to invoke a Worker. For example, if you want to put a worker on myname.example.com
, and you have added example.com
to Cloudflare but have not added any DNS records for myname.example.com
, any request to myname.example.com
will result in the error ERR_NAME_NOT_RESOLVED
.