I'm using Express 5.1.0 with Node.js v22.19.0, and I want to define a route where the parameter is optional, like /directory or /directory/someFolder.
Here's the code I tried:
import express from 'express';
import { readdir, stat } from 'node:fs/promises';
const app = express();
app.get('/directory/:foldername?', async (req, res) => {
const { foldername } = req.params;
const targetPath = foldername ? `./storage/${foldername}` : './storage';
const fileList = await readdir(targetPath);
const resData = [];
for (const item of fileList) {
const stats = await stat(`${targetPath}/${item}`);
resData.push({ name: item, isDirectory: stats.isDirectory() });
}
res.json(resData);
});
app.listen(3000);
But when I run this, I get the following error:
PathError [TypeError]: Unexpected ? at index 20, expected end: /directory/:foldername?
at consumeUntil (.../node_modules/path-to-regexp/dist/index.js:153:19)
at parse (.../node_modules/path-to-regexp/dist/index.js:157:26)
at pathToRegexp (.../node_modules/path-to-regexp/dist/index.js:267:58)
...
originalPath: '/directory/:foldername?'
What I've found so far:
In Express 4.x, :param? worked fine for optional parameters.
Express 5 uses a newer path-to-regexp which seems to reject ? at the end of a parameter.
I tried /directory/:foldername(*)? but that also throws Missing parameter name errors.
I expected the route /directory/:foldername? to let me hit both:
GET /directory → list files in ./storage
GET /directory/myFolder → list files in ./storage/myFolder
That's how it worked in Express 4.
But in Express 5.1.0, when I try this:
app.get('/directory/:foldername?', handler);
it immediately crashes with the PathError [TypeError]: Unexpected ? at index....
I also tried:
app.get('/directory/:foldername(*)?', handler);
but that throws a different error: Missing parameter name at index....
Express 5 uses curly braces ({ }) to denote optional path elements:
app.get('/directory{/:foldername}', async (req, res) => {
// Here -------^------------^