Dynamic Routes
Defining static routes may not be enough for some applications. You may need a worker to process URLs that includes identifiers. To create a worker associated with a dynamic route, include the route parameter in brackets when setting the worker filename.
For example, imagine you want a worker that replies to the following URLs:
/show/1
/show/2
With dynamic routes, you can create a worker with the show/[id].js
filename. This worker will reply to any /show/X
route automatically.
After defining the route paremeters, the worker receives a special argument called params
. It includes the value of all defined parameters. Note that the name of the parameter will be defined by the text between the brackets.
Check these guides to understand how to read parameters in the different supported languages:
- Dynamic routes in JavaScript
- Dynamic routes in Rust
- Dynamic routes in Python
- Dynamic routes in Ruby
- Dynamic routes in Go
- Dynamic routes in Zig
Dynamic routes and folders
Folders can follow this pattern too. You can define a folder that has a route parameter:
$ tree ./examples/with-params
./examples/with-params
├── [id]
└── fixed.js
In this case, the ./[id]/fixed.js
worker can reply to URLs like /abc/fixed
and /test/fixed
.
Multiple parameters
As both files and folders can be dynamic, workers may receive multiple parameters. The params
object includes the value of all the different parameters.
$ tree .
.
├── [resource]
└── [id]
└── show.js
In this case, the ./[resource]/[id]/show.js
worker replies to URLs like /articles/2/show
.
Catch-all routes
Catch-all routes are route segments that can be matched with any path segment on the route. For example, you can use catch-all routes by having a directory structure like the following:
$ tree .
.
└── [...slug]
└── index.js
This means, that the JavaScript worker at [...slug]/index.js
will serve any path beneath. You can mix and match specific routes with catch-all routes. For example, given the following directory structure:
$ tree .
.
├── about.js
└── [...slug]
└── index.js
In this example, two workers are fulfilling HTTP requests:
/about
is served by theabout.js
worker.- Anything else under
/
is served by the[...slug]/index.js
worker.
You can also place multiple catch-all routes as long as they are splitted by a non-catch-all segment. For example:
$ tree .
.
├── about.js
├── other
│ └── [...slug]
│ └── index.js
└── [...slug]
└── index.js
Here, we have the same structure as in the previous example, but we have two catch-all, under two different roots:
- One catch-all,
[...slug]/index.js
is serving all requests, except for requests whose path starts with/about
or/other
. - Another catch-all,
other/[...slug]/index.js
serves all requests under the/other
path.
You can also define segments at at the trailing of the URL, by having a worker in the filesystem of the form /some/resource/[...slug].js
. This worker will serve requests at the path /some/resource/<slug>
.
Routing priority
Given catch-all routes could potentially shadow other routes, it is important to settle precedence when routing requests. The rule of thumb is more specific routes win. For example, a route with no catch-all will always win against a route with catch-all when they are at the same depth.
Language compatibility
Language | Dynamic routes |
---|---|
JavaScript | ✅ |
Rust | ✅ |
Go | ✅ |
Ruby | ✅ |
Python | ✅ |
Zig | ✅ |