Express.js routing: optional spat param?

I have a route that looks like this:

    // do something when there is no splat
  } else {
    // do something with splat

however, this doesn't work - if I call path/foo/bar it hits the route, but if I call path/foo, it doesn't.

Is it possible to have an optional splat param, or do I have to use a regex to detect this?


to be clearer, here are the requirements I'm trying to achieve:

  • the first and second params are required
  • the first param is static, the second is a named param.
  • any number of optional additional params can be appended and still hit the route.

I just had the same problem and solved it. This is what I used:

app.get('path/:required/:optional?*, ...)

This should work for path/meow, path/meow/voof, path/meow/voof/moo/etc...

It seems by dropping the / between ? and *, the last / becomes optional too while :optional? remains optional.

This works for /path and /path/foo on express 4, note * before ?

router.get('/path/:id*?', function(req, res, next) {
    res.render('page', { title: });

Will this do what you're after?

    // do something when there is no optionalParam
  } else {
    // do something with optionalParam

More on Express' routing here, if you haven't looked:

Here's the current way I'm solving this problem, it doesn't appear that express supports any number of splat params with an optional named param:

  // Note: this is all hacked together because express does not appear to support optional splats.
  var params = req.params[1] ? [req.params[1]] : [],
      name = req.params[0];
    // do something when there is no splat
  } else {
    // do something with splat

I'd love to have this use named params for readability and consistency - if another answer surfaces that allows this I'll accept it.

The above solutions using optional doesn't work in Express 4. And I tried couple of ways using search patterns, but not working either. And then I found this method and seems fired for unlimited nested path,

// this will only be invoked if the path starts with /bar from the mount point
router.use('/bar', function(req, res, next) {
  // ... maybe some additional /bar logging ...

  // to get the url after bar, you can try
  var filepath = req.originalUrl.replace(req.baseUrl, "");


It's match all /bar, /bar/z, /bar/a/b/c etc. And after that, you can read req.originalUrl, since params are not filled, ex. you can try compare baseUrl and originalUrl to get the remaining path.