From 95dd62293e46a4d6826637b7bfdd49fca7bcf494 Mon Sep 17 00:00:00 2001 From: Akshay Anand Date: Sun, 19 Jul 2026 03:22:30 +0530 Subject: [PATCH 01/18] docs: mention wildcard parameters in route parameters guide --- src/content/docs/en/5x/guide/routing.mdx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/content/docs/en/5x/guide/routing.mdx b/src/content/docs/en/5x/guide/routing.mdx index cc05cefe3e..ab2a1dd13f 100644 --- a/src/content/docs/en/5x/guide/routing.mdx +++ b/src/content/docs/en/5x/guide/routing.mdx @@ -275,6 +275,8 @@ app.get('/users/:userId/books/:bookId', (req, res) => { }); ``` +Wildcard parameters (`*`) are also supported in Express 5. Unlike named parameters (`:`), they capture one or more path segments and expose them as an array in `req.params`. See the [Wildcards](#wildcards) section above for details and examples. + In TypeScript, `@types/express` infers the parameters from the route path, so in the handler above `req.params.userId` and `req.params.bookId` are already typed as `string` with no extra annotation. Reading a name that is not in the route (such as `req.params.other`) is a type error. You only need From f676181e28e2e3d57b42123e073ca83991dbc2a2 Mon Sep 17 00:00:00 2001 From: Akshay Anand Date: Wed, 22 Jul 2026 13:38:19 +0530 Subject: [PATCH 02/18] docs: address review feedback for wildcard parameters --- src/content/api/4x/api/request/index.mdx | 6 ++++++ src/content/api/5x/api/request/index.mdx | 6 ++++++ src/content/docs/en/5x/guide/routing.mdx | 6 +++++- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/content/api/4x/api/request/index.mdx b/src/content/api/4x/api/request/index.mdx index 3a05b00d06..83c0394cf0 100644 --- a/src/content/api/4x/api/request/index.mdx +++ b/src/content/api/4x/api/request/index.mdx @@ -399,6 +399,12 @@ app.use('/admin', function (req: Request, res: Response, next: NextFunction) { ### req.params + + +Wildcard parameters (`*`) are introduced in Express 5. See the [migration guide to Express 5](https://expressjs.com/en/guide/migrating-5/#path-route-matching-syntax) for details. + + + This property is an object containing properties mapped to the [named route "parameters"](/guide/routing/#route-parameters). For example, if you have the route `/user/:name`, then the "name" property is available as `req.params.name`. This object defaults to `{}`. diff --git a/src/content/api/5x/api/request/index.mdx b/src/content/api/5x/api/request/index.mdx index 9960e91997..5c5ec14b6d 100644 --- a/src/content/api/5x/api/request/index.mdx +++ b/src/content/api/5x/api/request/index.mdx @@ -391,6 +391,12 @@ app.use('/admin', (req: Request, res: Response, next: NextFunction) => { ### req.params + + +Wildcard parameters (`*`) are only supported in Express 5. Unlike named parameters (`:`), they capture one or more path segments and expose them as an array in `req.params`. See the [migration guide](https://expressjs.com/en/guide/migrating-5/#path-route-matching-syntax) for details. + + + This property is an object containing properties mapped to the [named route "parameters"](/guide/routing/#route-parameters). For example, if you have the route `/user/:name`, then the "name" property is available as `req.params.name`. This object defaults to `Object.create(null)` when using string paths, but remains a standard object with a normal prototype when the path is defined with a regular expression. diff --git a/src/content/docs/en/5x/guide/routing.mdx b/src/content/docs/en/5x/guide/routing.mdx index ab2a1dd13f..fc01596a98 100644 --- a/src/content/docs/en/5x/guide/routing.mdx +++ b/src/content/docs/en/5x/guide/routing.mdx @@ -275,7 +275,11 @@ app.get('/users/:userId/books/:bookId', (req, res) => { }); ``` -Wildcard parameters (`*`) are also supported in Express 5. Unlike named parameters (`:`), they capture one or more path segments and expose them as an array in `req.params`. See the [Wildcards](#wildcards) section above for details and examples. + + +Wildcard parameters (`*`) are only supported in Express 5. Unlike named parameters (`:`), they capture one or more path segments and expose them as an array in `req.params`. See the [Wildcards](#wildcards) section above or the [migration guide](https://expressjs.com/en/guide/migrating-5/#path-route-matching-syntax) for details and examples. + + In TypeScript, `@types/express` infers the parameters from the route path, so in the handler above `req.params.userId` and `req.params.bookId` are already typed as `string` with no extra annotation. From e3574e27bbaeafbaa6c99512a1de7f28b802d0eb Mon Sep 17 00:00:00 2001 From: Akshay Anand Date: Wed, 22 Jul 2026 14:10:02 +0530 Subject: [PATCH 03/18] docs: clarify Express 4 wildcard parameter behavior --- src/content/api/4x/api/request/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/api/4x/api/request/index.mdx b/src/content/api/4x/api/request/index.mdx index 83c0394cf0..e938e6548b 100644 --- a/src/content/api/4x/api/request/index.mdx +++ b/src/content/api/4x/api/request/index.mdx @@ -401,7 +401,7 @@ app.use('/admin', function (req: Request, res: Response, next: NextFunction) { -Wildcard parameters (`*`) are introduced in Express 5. See the [migration guide to Express 5](https://expressjs.com/en/guide/migrating-5/#path-route-matching-syntax) for details. +In Express 4, wildcard matches are exposed as unnamed parameters (for example, `req.params[0]`) and return a string. Express 5 introduces named wildcard parameters that are exposed as arrays. See the [migration guide](https://expressjs.com/en/guide/migrating-5/#path-route-matching-syntax) for details. From d20b295f9f4d28a143d3a3d1996551a115f5075a Mon Sep 17 00:00:00 2001 From: Akshay Anand Date: Wed, 22 Jul 2026 14:21:53 +0530 Subject: [PATCH 04/18] docs: update Express 4 wildcard migration note --- src/content/api/4x/api/request/index.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/content/api/4x/api/request/index.mdx b/src/content/api/4x/api/request/index.mdx index e938e6548b..628c57318c 100644 --- a/src/content/api/4x/api/request/index.mdx +++ b/src/content/api/4x/api/request/index.mdx @@ -399,9 +399,9 @@ app.use('/admin', function (req: Request, res: Response, next: NextFunction) { ### req.params - + -In Express 4, wildcard matches are exposed as unnamed parameters (for example, `req.params[0]`) and return a string. Express 5 introduces named wildcard parameters that are exposed as arrays. See the [migration guide](https://expressjs.com/en/guide/migrating-5/#path-route-matching-syntax) for details. +In Express 4, wildcards (`*`) are unnamed, whereas in Express 5, wildcards must be explicitly named (e.g., `/*splat`). Please check the [migration guide to 5.x](https://expressjs.com/en/guide/migrating-5/#path-route-matching-syntax) before upgrading your routes. From f79c508fafc976f41bafb091064de3d27a98995e Mon Sep 17 00:00:00 2001 From: Akshay Anand <147163632+Akshay4754@users.noreply.github.com> Date: Wed, 22 Jul 2026 14:40:51 +0530 Subject: [PATCH 05/18] Update src/content/api/4x/api/request/index.mdx Co-authored-by: shubham oulkar Signed-off-by: Akshay Anand <147163632+Akshay4754@users.noreply.github.com> --- src/content/api/4x/api/request/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/api/4x/api/request/index.mdx b/src/content/api/4x/api/request/index.mdx index 628c57318c..18199ea0df 100644 --- a/src/content/api/4x/api/request/index.mdx +++ b/src/content/api/4x/api/request/index.mdx @@ -399,7 +399,7 @@ app.use('/admin', function (req: Request, res: Response, next: NextFunction) { ### req.params - + In Express 4, wildcards (`*`) are unnamed, whereas in Express 5, wildcards must be explicitly named (e.g., `/*splat`). Please check the [migration guide to 5.x](https://expressjs.com/en/guide/migrating-5/#path-route-matching-syntax) before upgrading your routes. From fa31c8a9d81d3b5034ae0a00ccfc9fd13f98d21f Mon Sep 17 00:00:00 2001 From: Akshay Anand Date: Sat, 25 Jul 2026 02:27:49 +0530 Subject: [PATCH 06/18] docs: remove redundant Express 5 wording and simplified it --- src/content/api/5x/api/request/index.mdx | 2 +- src/content/docs/en/5x/guide/routing.mdx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/content/api/5x/api/request/index.mdx b/src/content/api/5x/api/request/index.mdx index 5c5ec14b6d..87e1cbe5d0 100644 --- a/src/content/api/5x/api/request/index.mdx +++ b/src/content/api/5x/api/request/index.mdx @@ -393,7 +393,7 @@ app.use('/admin', (req: Request, res: Response, next: NextFunction) => { -Wildcard parameters (`*`) are only supported in Express 5. Unlike named parameters (`:`), they capture one or more path segments and expose them as an array in `req.params`. See the [migration guide](https://expressjs.com/en/guide/migrating-5/#path-route-matching-syntax) for details. +Wildcard parameters (`*`) capture one or more path segments and expose them as an array in `req.params`. See the [migration guide](https://expressjs.com/en/guide/migrating-5/#path-route-matching-syntax) for details. diff --git a/src/content/docs/en/5x/guide/routing.mdx b/src/content/docs/en/5x/guide/routing.mdx index fc01596a98..a06ada064c 100644 --- a/src/content/docs/en/5x/guide/routing.mdx +++ b/src/content/docs/en/5x/guide/routing.mdx @@ -277,7 +277,7 @@ app.get('/users/:userId/books/:bookId', (req, res) => { -Wildcard parameters (`*`) are only supported in Express 5. Unlike named parameters (`:`), they capture one or more path segments and expose them as an array in `req.params`. See the [Wildcards](#wildcards) section above or the [migration guide](https://expressjs.com/en/guide/migrating-5/#path-route-matching-syntax) for details and examples. +Wildcard parameters (`*`) capture one or more path segments and expose them as an array in `req.params`. See the [Wildcards](#wildcards) section above or the [migration guide](https://expressjs.com/en/guide/migrating-5/#path-route-matching-syntax) for details and examples. From 1e0f9fdd5ed4050585cbdfa9e4dc959ae4db2887 Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Tue, 28 Jul 2026 11:16:03 -0500 Subject: [PATCH 07/18] docs: update wildcard parameter documentation for clarity and examples --- src/content/api/4x/api/request/index.mdx | 6 ------ src/content/docs/en/4x/guide/routing.mdx | 20 ++++++++++++++++++++ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/content/api/4x/api/request/index.mdx b/src/content/api/4x/api/request/index.mdx index 18199ea0df..3a05b00d06 100644 --- a/src/content/api/4x/api/request/index.mdx +++ b/src/content/api/4x/api/request/index.mdx @@ -399,12 +399,6 @@ app.use('/admin', function (req: Request, res: Response, next: NextFunction) { ### req.params - - -In Express 4, wildcards (`*`) are unnamed, whereas in Express 5, wildcards must be explicitly named (e.g., `/*splat`). Please check the [migration guide to 5.x](https://expressjs.com/en/guide/migrating-5/#path-route-matching-syntax) before upgrading your routes. - - - This property is an object containing properties mapped to the [named route "parameters"](/guide/routing/#route-parameters). For example, if you have the route `/user/:name`, then the "name" property is available as `req.params.name`. This object defaults to `{}`. diff --git a/src/content/docs/en/4x/guide/routing.mdx b/src/content/docs/en/4x/guide/routing.mdx index 3924d9e7f9..a9e876710d 100644 --- a/src/content/docs/en/4x/guide/routing.mdx +++ b/src/content/docs/en/4x/guide/routing.mdx @@ -235,6 +235,26 @@ app.get('/ab(cd)?e', (req: Request, res: Response) => { }); ``` +A wildcard (`*`) on its own matches any path segment. For example, this route path will match `/file/javascripts/jquery.js`, `/file/style.css`, and so on. 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 From f8637252b0480c0029cffc2d6558649a397431fd Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Tue, 28 Jul 2026 11:17:30 -0500 Subject: [PATCH 08/18] docs: remove redundant alert about wildcard parameters from request documentation --- src/content/api/5x/api/request/index.mdx | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/content/api/5x/api/request/index.mdx b/src/content/api/5x/api/request/index.mdx index 87e1cbe5d0..9960e91997 100644 --- a/src/content/api/5x/api/request/index.mdx +++ b/src/content/api/5x/api/request/index.mdx @@ -391,12 +391,6 @@ app.use('/admin', (req: Request, res: Response, next: NextFunction) => { ### req.params - - -Wildcard parameters (`*`) capture one or more path segments and expose them as an array in `req.params`. See the [migration guide](https://expressjs.com/en/guide/migrating-5/#path-route-matching-syntax) for details. - - - This property is an object containing properties mapped to the [named route "parameters"](/guide/routing/#route-parameters). For example, if you have the route `/user/:name`, then the "name" property is available as `req.params.name`. This object defaults to `Object.create(null)` when using string paths, but remains a standard object with a normal prototype when the path is defined with a regular expression. From e66caf69a938986e7957f433a04e9117f55c4277 Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Tue, 28 Jul 2026 11:36:55 -0500 Subject: [PATCH 09/18] docs: enhance wildcard parameters section with detailed explanations and examples --- src/content/docs/en/5x/guide/routing.mdx | 150 +++++++++++------------ 1 file changed, 74 insertions(+), 76 deletions(-) diff --git a/src/content/docs/en/5x/guide/routing.mdx b/src/content/docs/en/5x/guide/routing.mdx index a06ada064c..282fb5be43 100644 --- a/src/content/docs/en/5x/guide/routing.mdx +++ b/src/content/docs/en/5x/guide/routing.mdx @@ -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. @@ -153,74 +153,6 @@ 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'); -}); -``` - The characters `?`, `+`, `*`, `[]`, and `()` are reserved and cannot be used as literal characters in route paths. Use `\` to escape them if needed. @@ -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) (`{...}`). + +### Named parameters + +Named parameters capture a single path segment at their position in the URL. ``` Route path: /users/:userId/books/:bookId @@ -275,12 +211,6 @@ app.get('/users/:userId/books/:bookId', (req, res) => { }); ``` - - -Wildcard parameters (`*`) capture one or more path segments and expose them as an array in `req.params`. See the [Wildcards](#wildcards) section above or the [migration guide](https://expressjs.com/en/guide/migrating-5/#path-route-matching-syntax) for details and examples. - - - In TypeScript, `@types/express` infers the parameters from the route path, so in the handler above `req.params.userId` and `req.params.bookId` are already typed as `string` with no extra annotation. Reading a name that is not in the route (such as `req.params.other`) is a type error. You only need @@ -324,6 +254,74 @@ See the [path route matching syntax](/guide/migrating-5#path-route-matching-synt +### 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 = [] + // 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'); +}); +``` + ## 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. From 7026eecfea4dba7929f9cfcc62816d26a08a61d4 Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Tue, 28 Jul 2026 11:42:04 -0500 Subject: [PATCH 10/18] docs: clarify route paths and wildcard parameter behavior in routing documentation --- src/content/docs/en/4x/guide/routing.mdx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/content/docs/en/4x/guide/routing.mdx b/src/content/docs/en/4x/guide/routing.mdx index a9e876710d..7476ae837c 100644 --- a/src/content/docs/en/4x/guide/routing.mdx +++ b/src/content/docs/en/4x/guide/routing.mdx @@ -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. @@ -368,6 +368,8 @@ 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 `*`. +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 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. From e61ffd13cfbbdd8dc3ceaa6632a070f92b108774 Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Tue, 28 Jul 2026 11:46:07 -0500 Subject: [PATCH 11/18] docs: add example for wildcard route parameters in routing documentation --- src/content/docs/en/4x/guide/routing.mdx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/content/docs/en/4x/guide/routing.mdx b/src/content/docs/en/4x/guide/routing.mdx index 7476ae837c..509410ac8b 100644 --- a/src/content/docs/en/4x/guide/routing.mdx +++ b/src/content/docs/en/4x/guide/routing.mdx @@ -370,6 +370,12 @@ The [`*`](https://github.com/expressjs/express/issues/2495) character in regular 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. From f91f1cc9f1ab8ae03df20f7ece8c6c83d615b2c7 Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Tue, 28 Jul 2026 12:02:18 -0500 Subject: [PATCH 12/18] docs: update wildcard route parameter examples for clarity and optionality --- src/content/docs/en/5x/guide/routing.mdx | 38 ++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/src/content/docs/en/5x/guide/routing.mdx b/src/content/docs/en/5x/guide/routing.mdx index 282fb5be43..ae1ffb425a 100644 --- a/src/content/docs/en/5x/guide/routing.mdx +++ b/src/content/docs/en/5x/guide/routing.mdx @@ -283,7 +283,7 @@ 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 / => req.params = {}, splat is omitted // GET /foo/bar => req.params.splat = [ 'foo', 'bar' ] res.send('ok'); }); @@ -294,7 +294,7 @@ import { type Request, type Response } from 'express'; // Matches / , /foo , /foo/bar , etc. app.get('/{*splat}', (req: Request, res: Response) => { - // GET / => req.params.splat = [] + // GET / => req.params = {}, splat is omitted // GET /foo/bar => req.params.splat = [ 'foo', 'bar' ] res.send('ok'); }); @@ -322,6 +322,40 @@ app.get('/:file{.:ext}', (req: Request, res: Response) => { }); ``` +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'); +}); +``` + ## 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. From 10b8946f38dc7cccc53e473d3769f048e0474782 Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Tue, 28 Jul 2026 12:09:46 -0500 Subject: [PATCH 13/18] docs: clarify behavior of route examples with respect to strict routing setting --- src/content/docs/en/5x/guide/routing.mdx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/content/docs/en/5x/guide/routing.mdx b/src/content/docs/en/5x/guide/routing.mdx index ae1ffb425a..a02738048d 100644 --- a/src/content/docs/en/5x/guide/routing.mdx +++ b/src/content/docs/en/5x/guide/routing.mdx @@ -356,6 +356,8 @@ app.get('/order{/:id}', (req: Request, res: Response) => { }); ``` +The examples above behave the same regardless of the [`strict routing` setting](/api/application/#application-settings). As with any other route, that setting only changes whether a trailing slash (such as `/order/`) is treated as a different path. + ## 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. From 81c7dd2dac2c7884adeb17b67225d9e950799f43 Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Tue, 28 Jul 2026 12:14:06 -0500 Subject: [PATCH 14/18] docs: clarify behavior of optional segments in route parameters documentation --- src/content/api/5x/api/request/index.mdx | 2 ++ src/content/docs/en/5x/guide/routing.mdx | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/content/api/5x/api/request/index.mdx b/src/content/api/5x/api/request/index.mdx index 9960e91997..9518b49c4a 100644 --- a/src/content/api/5x/api/request/index.mdx +++ b/src/content/api/5x/api/request/index.mdx @@ -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 nth capture group. ```js diff --git a/src/content/docs/en/5x/guide/routing.mdx b/src/content/docs/en/5x/guide/routing.mdx index a02738048d..ece2ae69d2 100644 --- a/src/content/docs/en/5x/guide/routing.mdx +++ b/src/content/docs/en/5x/guide/routing.mdx @@ -191,7 +191,7 @@ 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. They come in three forms: [named parameters](#named-parameters) (`:name`), [wildcards](#wildcards) (`*name`), and [optional segments](#optional-segments) (`{...}`). +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 From 96a8a4d1a2da501fbcd4d7acae02db1019d7b9b0 Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Tue, 28 Jul 2026 12:17:07 -0500 Subject: [PATCH 15/18] docs: update routing documentation to clarify reserved characters and valid parameter names --- src/content/docs/en/5x/guide/routing.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/content/docs/en/5x/guide/routing.mdx b/src/content/docs/en/5x/guide/routing.mdx index ece2ae69d2..e79d19cf8a 100644 --- a/src/content/docs/en/5x/guide/routing.mdx +++ b/src/content/docs/en/5x/guide/routing.mdx @@ -155,7 +155,7 @@ app.get('/random.text', (req: Request, res: Response) => { -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. @@ -229,7 +229,7 @@ app.get('/users/:userId/books/:bookId', sendParams); -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"`. From e9503e12e33ef21ebd8716492de0767a5aa2690a Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Tue, 28 Jul 2026 12:22:53 -0500 Subject: [PATCH 16/18] docs: enhance wildcard and named parameter descriptions for clarity --- src/content/docs/en/4x/guide/routing.mdx | 2 +- src/content/docs/en/5x/guide/routing.mdx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/content/docs/en/4x/guide/routing.mdx b/src/content/docs/en/4x/guide/routing.mdx index 509410ac8b..e29a062b19 100644 --- a/src/content/docs/en/4x/guide/routing.mdx +++ b/src/content/docs/en/4x/guide/routing.mdx @@ -235,7 +235,7 @@ app.get('/ab(cd)?e', (req: Request, res: Response) => { }); ``` -A wildcard (`*`) on its own matches any path segment. For example, this route path will match `/file/javascripts/jquery.js`, `/file/style.css`, and so on. Wildcards are unnamed, so the matched value is available as `req.params[0]` instead of a named parameter. +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) => { diff --git a/src/content/docs/en/5x/guide/routing.mdx b/src/content/docs/en/5x/guide/routing.mdx index e79d19cf8a..5eb558a0ea 100644 --- a/src/content/docs/en/5x/guide/routing.mdx +++ b/src/content/docs/en/5x/guide/routing.mdx @@ -195,7 +195,7 @@ Route parameters are named URL segments that are used to capture the values spec ### Named parameters -Named parameters capture a single path segment at their position in the URL. +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 @@ -249,7 +249,7 @@ req.params: { "genus": "Prunus", "species": "persica" } -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. From 07b11d82df9d0092fc127cacfe04621d3670ee22 Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Tue, 28 Jul 2026 12:32:56 -0500 Subject: [PATCH 17/18] docs: clarify the impact of strict routing on route matching behavior --- src/content/docs/en/5x/guide/routing.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/docs/en/5x/guide/routing.mdx b/src/content/docs/en/5x/guide/routing.mdx index 5eb558a0ea..6ada5f8820 100644 --- a/src/content/docs/en/5x/guide/routing.mdx +++ b/src/content/docs/en/5x/guide/routing.mdx @@ -356,7 +356,7 @@ app.get('/order{/:id}', (req: Request, res: Response) => { }); ``` -The examples above behave the same regardless of the [`strict routing` setting](/api/application/#application-settings). As with any other route, that setting only changes whether a trailing slash (such as `/order/`) is treated as a different path. +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 From 9718688a7333152d9b21e1e836e2dd989438ac79 Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Tue, 28 Jul 2026 12:42:46 -0500 Subject: [PATCH 18/18] docs: improve clarity in app.route() section regarding modular routes and path parameters --- src/content/docs/en/4x/guide/routing.mdx | 4 ++-- src/content/docs/en/5x/guide/routing.mdx | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/content/docs/en/4x/guide/routing.mdx b/src/content/docs/en/4x/guide/routing.mdx index e29a062b19..f5ae694e44 100644 --- a/src/content/docs/en/4x/guide/routing.mdx +++ b/src/content/docs/en/4x/guide/routing.mdx @@ -572,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()`. @@ -705,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 }); diff --git a/src/content/docs/en/5x/guide/routing.mdx b/src/content/docs/en/5x/guide/routing.mdx index 6ada5f8820..ca4da2e2ff 100644 --- a/src/content/docs/en/5x/guide/routing.mdx +++ b/src/content/docs/en/5x/guide/routing.mdx @@ -554,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()`. @@ -687,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 });