Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
95dd622
docs: mention wildcard parameters in route parameters guide
Akshay4754 Jul 18, 2026
f676181
docs: address review feedback for wildcard parameters
Akshay4754 Jul 22, 2026
e3574e2
docs: clarify Express 4 wildcard parameter behavior
Akshay4754 Jul 22, 2026
d20b295
docs: update Express 4 wildcard migration note
Akshay4754 Jul 22, 2026
f79c508
Update src/content/api/4x/api/request/index.mdx
Akshay4754 Jul 22, 2026
fa31c8a
docs: remove redundant Express 5 wording and simplified it
Akshay4754 Jul 24, 2026
1e0f9fd
docs: update wildcard parameter documentation for clarity and examples
bjohansebas Jul 28, 2026
f863725
docs: remove redundant alert about wildcard parameters from request d…
bjohansebas Jul 28, 2026
e66caf6
docs: enhance wildcard parameters section with detailed explanations …
bjohansebas Jul 28, 2026
7026eec
docs: clarify route paths and wildcard parameter behavior in routing …
bjohansebas Jul 28, 2026
e61ffd1
docs: add example for wildcard route parameters in routing documentation
bjohansebas Jul 28, 2026
f91f1cc
docs: update wildcard route parameter examples for clarity and option…
bjohansebas Jul 28, 2026
10b8946
docs: clarify behavior of route examples with respect to strict routi…
bjohansebas Jul 28, 2026
81c7dd2
docs: clarify behavior of optional segments in route parameters docum…
bjohansebas Jul 28, 2026
96a8a4d
docs: update routing documentation to clarify reserved characters and…
bjohansebas Jul 28, 2026
e9503e1
docs: enhance wildcard and named parameter descriptions for clarity
bjohansebas Jul 28, 2026
07b11d8
docs: clarify the impact of strict routing on route matching behavior
bjohansebas Jul 28, 2026
9718688
docs: improve clarity in app.route() section regarding modular routes…
bjohansebas Jul 28, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/content/api/5x/api/request/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,8 @@ app.get('/files/*file', (req: Request, res: Response) => {
});
```

Parameters defined in [optional segments](/guide/routing/#optional-segments) that are not present in the request URL are omitted from `req.params` entirely.

When you use a regular expression for the route definition, capture groups are provided as integer keys using `req.params[n]`, where `n` is the n<sup>th</sup> capture group.

```js
Expand Down
34 changes: 31 additions & 3 deletions src/content/docs/en/4x/guide/routing.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ app.all('/secret', (req: Request, res: Response, next: NextFunction) => {

## Route paths

Route paths, in combination with a request method, define the endpoints at which requests can be made. Route paths can be strings, string patterns, or regular expressions.
Route paths, in combination with a request method, define the endpoints at which requests can be made. Route paths can be strings, string patterns, or regular expressions. They can also capture values from the URL, as described in [Route parameters](#route-parameters) below.

<Alert type="info">

Expand Down Expand Up @@ -235,6 +235,26 @@ app.get('/ab(cd)?e', (req: Request, res: Response) => {
});
```

A wildcard (`*`) on its own matches anything at its position, including entire subpaths. For example, this route path will match `/file/style.css` as well as `/file/javascripts/jquery.js`. Wildcards are unnamed, so the matched value is available as `req.params[0]` instead of a named parameter.

```js
app.get('/file/*', (req, res) => {
// GET /file/javascripts/jquery.js
res.send(req.params[0]);
// => 'javascripts/jquery.js'
});
```

```ts
import { type Request, type Response } from 'express';

app.get('/file/*', (req: Request, res: Response) => {
// GET /file/javascripts/jquery.js
res.send(req.params[0]);
// => 'javascripts/jquery.js'
});
```

### Route paths based on regular expressions

<Alert type="alert">
Expand Down Expand Up @@ -348,6 +368,14 @@ characters with an additional backslash, for example `\\d+`.
The [`*`](https://github.com/expressjs/express/issues/2495) character in regular expressions is not interpreted in the usual way. As a workaround, use `{0,}` instead of `*`.
</Alert>

Unlike named route parameters, wildcard (`*`) matches in [string patterns](#route-paths-based-on-string-patterns) and capture groups in regular expressions are unnamed: their values are available by position, as `req.params[0]`, `req.params[1]`, and so on.

```
Route path: /file/*/size/*
Request URL: http://localhost:3000/file/javascripts/jquery.js/size/large
req.params: { "0": "javascripts/jquery.js", "1": "large" }
```

## Route handlers

You can provide multiple callback functions that behave like [middleware](/guide/using-middleware) to handle a request. The only exception is that these callbacks might invoke `next('route')` to bypass the remaining route callbacks. You can use this mechanism to impose pre-conditions on a route, then pass control to subsequent routes if there's no reason to proceed with the current route.
Expand Down Expand Up @@ -544,7 +572,7 @@ The methods on the response object (`res`) in the following table can send a res
## app.route()

You can create chainable route handlers for a route path by using `app.route()`.
Because the path is specified at a single location, creating modular routes is helpful, as is reducing redundancy and typos. For more information about routes, see: [Router() documentation](/api/router).
Because the path is specified in a single location, this helps to create modular routes and reduces redundancy and typos. For more information about routes, see the [Router() documentation](/api/router).

Here is an example of chained route handlers that are defined by using `app.route()`.

Expand Down Expand Up @@ -677,7 +705,7 @@ app.use('/birds', birds);

The app will now be able to handle requests to `/birds` and `/birds/about`, as well as call the `timeLog` middleware function that is specific to the route.

But if the parent route `/birds` has path parameters, it will not be accessible by default from the sub-routes. To make it accessible, you will need to pass the `mergeParams` option to the Router constructor [reference](/api/application#appuse).
But if the parent route `/birds` has path parameters, it will not be accessible by default from the sub-routes. To make it accessible, you will need to pass the `mergeParams` option to the [Router constructor](/api/express/#expressrouter).

```js
const router = express.Router({ mergeParams: true });
Expand Down
190 changes: 115 additions & 75 deletions src/content/docs/en/5x/guide/routing.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ app.all('/secret', (req: Request, res: Response, next: NextFunction) => {

## Route paths

Route paths, in combination with a request method, define the endpoints at which requests can be made. Route paths can be strings or regular expressions.
Route paths, in combination with a request method, define the endpoints at which requests can be made. Route paths can be strings or regular expressions. They can also capture values from the URL, as described in [Route parameters](#route-parameters) below.

<Alert type="info">

Expand Down Expand Up @@ -153,77 +153,9 @@ app.get('/random.text', (req: Request, res: Response) => {
});
```

### Wildcards

Wildcards match any path after a prefix. They must have a name, just like route parameters, and are captured as arrays of path segments.

```js
app.get('/files/*filepath', (req, res) => {
// GET /files/images/logo.png
console.dir(req.params.filepath);
// => [ 'images', 'logo.png' ]
res.send(`File: ${req.params.filepath.join('/')}`);
});
```

```ts
import { type Request, type Response } from 'express';

app.get('/files/*filepath', (req: Request<{ filepath: string[] }>, res: Response) => {
// GET /files/images/logo.png
console.dir(req.params.filepath);
// => [ 'images', 'logo.png' ]
res.send(`File: ${req.params.filepath.join('/')}`);
});
```

To also match the root path, wrap the wildcard in braces:

```js
// Matches / , /foo , /foo/bar , etc.
app.get('/{*splat}', (req, res) => {
// GET / => req.params.splat = []
// GET /foo/bar => req.params.splat = [ 'foo', 'bar' ]
res.send('ok');
});
```

```ts
import { type Request, type Response } from 'express';

// Matches / , /foo , /foo/bar , etc.
app.get('/{*splat}', (req: Request, res: Response) => {
// GET / => req.params.splat = []
// GET /foo/bar => req.params.splat = [ 'foo', 'bar' ]
res.send('ok');
});
```

### Optional segments

Use braces to define optional segments in a route path. When the segment is not present, the parameter is omitted from `req.params`.

```js
app.get('/:file{.:ext}', (req, res) => {
// GET /image.png => req.params = { file: 'image', ext: 'png' }
// GET /image => req.params = { file: 'image' }
res.send('ok');
});
```

```ts
import { type Request, type Response } from 'express';

app.get('/:file{.:ext}', (req: Request, res: Response) => {
// GET /image.png => req.params = { file: 'image', ext: 'png' }
// GET /image => req.params = { file: 'image' }
res.send('ok');
});
```

<Alert type="alert">

The characters `?`, `+`, `*`, `[]`, and `()` are reserved and cannot be used as literal characters in route paths. Use `\` to escape them if needed.
The characters `?`, `+`, `*`, `[]`, `()`, and `!` are reserved and cannot be used as literal characters in route paths, and braces are reserved for [optional segments](#optional-segments). Use `\` to escape them if needed.

</Alert>

Expand Down Expand Up @@ -259,7 +191,11 @@ app.get(/.*fly$/, (req: Request, res: Response) => {

## Route parameters

Route parameters are named URL segments that are used to capture the values specified at their position in the URL. The captured values are populated in the `req.params` object, with the name of the route parameter specified in the path as their respective keys.
Route parameters are named URL segments that are used to capture the values specified at their position in the URL. The captured values are populated in the `req.params` object, with the name of the route parameter specified in the path as their respective keys. They come in three forms: [named parameters](#named-parameters) (`:name`), [wildcards](#wildcards) (`*name`), and [optional segments](#optional-segments), which wrap either of them in braces.

### Named parameters

Named parameters capture a single path segment at their position in the URL, or part of one when combined with literal characters, as shown further below.

```
Route path: /users/:userId/books/:bookId
Expand Down Expand Up @@ -293,7 +229,7 @@ app.get('/users/:userId/books/:bookId', sendParams);

<Alert type="alert">

The name of route parameters must be made up of "word characters" ([A-Za-z0-9_]).
The name of route parameters must be a valid JavaScript identifier. Other names can be used by quoting them, for example `:"user-name"`.

</Alert>

Expand All @@ -313,11 +249,115 @@ req.params: { "genus": "Prunus", "species": "persica" }

<Alert type="alert">

Regexp characters are not supported in route paths. Use an array of paths or regular expressions instead.
Regexp characters are not supported inside string paths, so a parameter cannot be restricted with a suffix such as `:userId(\d+)`. Use an array of paths or a full regular expression instead.
See the [path route matching syntax](/guide/migrating-5#path-route-matching-syntax) for more information.

</Alert>

### Wildcards

Wildcards match any path after a prefix. Like other route parameters they must have a name, but they are captured as an array of path segments instead of a string.

```js
app.get('/files/*filepath', (req, res) => {
// GET /files/images/logo.png
console.dir(req.params.filepath);
// => [ 'images', 'logo.png' ]
res.send(`File: ${req.params.filepath.join('/')}`);
});
```

```ts
import { type Request, type Response } from 'express';

app.get('/files/*filepath', (req: Request<{ filepath: string[] }>, res: Response) => {
// GET /files/images/logo.png
console.dir(req.params.filepath);
// => [ 'images', 'logo.png' ]
res.send(`File: ${req.params.filepath.join('/')}`);
});
```

To also match the root path, wrap the wildcard in braces:

```js
// Matches / , /foo , /foo/bar , etc.
app.get('/{*splat}', (req, res) => {
// GET / => req.params = {}, splat is omitted
// GET /foo/bar => req.params.splat = [ 'foo', 'bar' ]
res.send('ok');
});
```

```ts
import { type Request, type Response } from 'express';

// Matches / , /foo , /foo/bar , etc.
app.get('/{*splat}', (req: Request, res: Response) => {
// GET / => req.params = {}, splat is omitted
// GET /foo/bar => req.params.splat = [ 'foo', 'bar' ]
res.send('ok');
});
```

### Optional segments

Use braces to define optional segments in a route path. When the segment is not present, the parameter is omitted from `req.params`.

```js
app.get('/:file{.:ext}', (req, res) => {
// GET /image.png => req.params = { file: 'image', ext: 'png' }
// GET /image => req.params = { file: 'image' }
res.send('ok');
});
```

```ts
import { type Request, type Response } from 'express';

app.get('/:file{.:ext}', (req: Request, res: Response) => {
// GET /image.png => req.params = { file: 'image', ext: 'png' }
// GET /image => req.params = { file: 'image' }
res.send('ok');
});
```

The braces can also wrap a whole parameter to make it optional. Note that everything inside the braces is optional, so the position of the slash matters:

```js
app.get('/user/{:id}', (req, res) => {
// GET /user/42 => req.params = { id: '42' }
// GET /user/ => req.params = {}
// GET /user => 404, only the parameter is optional
res.send('ok');
});

app.get('/order{/:id}', (req, res) => {
// GET /order/42 => req.params = { id: '42' }
// GET /order => req.params = {}, the whole segment is optional
res.send('ok');
});
```

```ts
import { type Request, type Response } from 'express';

app.get('/user/{:id}', (req: Request, res: Response) => {
// GET /user/42 => req.params = { id: '42' }
// GET /user/ => req.params = {}
// GET /user => 404, only the parameter is optional
res.send('ok');
});

app.get('/order{/:id}', (req: Request, res: Response) => {
// GET /order/42 => req.params = { id: '42' }
// GET /order => req.params = {}, the whole segment is optional
res.send('ok');
});
```

Do not confuse the position of the slash in the route path with the [`strict routing` setting](/api/application/#application-settings), which is about the request URL: it controls whether a URL ending in a slash that the route path does not require still matches. For example, a request for `/order/` matches the `/order{/:id}` route by default, but returns a 404 error when strict routing is enabled; the trailing slash of `/user/` is unaffected because the `/user/{:id}` route requires it. All the requests commented in the examples above behave the same regardless of that setting.

## Route handlers

You can provide multiple callback functions that behave like [middleware](/guide/using-middleware) to handle a request. The only exception is that these callbacks might invoke `next('route')` to bypass the remaining route callbacks. You can use this mechanism to impose pre-conditions on a route, then pass control to subsequent routes if there's no reason to proceed with the current route.
Expand Down Expand Up @@ -514,7 +554,7 @@ The methods on the response object (`res`) in the following table can send a res
## app.route()

You can create chainable route handlers for a route path by using `app.route()`.
Because the path is specified at a single location, creating modular routes is helpful, as is reducing redundancy and typos. For more information about routes, see: [Router() documentation](/api/router).
Because the path is specified in a single location, this helps to create modular routes and reduces redundancy and typos. For more information about routes, see the [Router() documentation](/api/router).

Here is an example of chained route handlers that are defined by using `app.route()`.

Expand Down Expand Up @@ -647,7 +687,7 @@ app.use('/birds', birds);

The app will now be able to handle requests to `/birds` and `/birds/about`, as well as call the `timeLog` middleware function that is specific to the route.

But if the parent route `/birds` has path parameters, it will not be accessible by default from the sub-routes. To make it accessible, you will need to pass the `mergeParams` option to the Router constructor [reference](/api/application#appuse).
But if the parent route `/birds` has path parameters, it will not be accessible by default from the sub-routes. To make it accessible, you will need to pass the `mergeParams` option to the [Router constructor](/api/express/#expressrouter).

```js
const router = express.Router({ mergeParams: true });
Expand Down
Loading