Routes' Matching Syntax

Most applications will use static routes like /about and dynamic routes like /users/:userId like we just saw in Dynamic Route Matching, but Vue Router has much more to offer!

TIP

For the sake of simplicity, all route records are omitting the component property to focus on the path value.

Custom Regexp in params

When defining a param like :userId, we internally use the following regexp ([^/]+) (at least one character that isn't a slash /) to extract params from URLs. This works well unless you need to differentiate two routes based on the param content. Imagine two routes /:orderId and /:productName, both would match the exact same URLs, so we need a way to differentiate them. The easiest way would be to add a static section to the path that differentiates them:

const routes = [
  // matches /o/3549
  { path: '/o/:orderId' },
  // matches /p/books
  { path: '/p/:productName' },
]

But in some scenarios we don't want to add that static section /o/p. However, orderId is always a number while productName can be anything, so we can specify a custom regexp for a param in parentheses:

const routes = [
  // /:orderId -> matches only numbers
  { path: '/:orderId(\\d+)' },
  // /:productName -> matches anything else
  { path: '/:productName' },
]

Now, going to /25 will match /:orderId while going to anything else will match /:productName. The order of the routes array doesn't even matter!

TIP

Make sure to escape backslashes (\) like we did with \d (becomes \\d) to actually pass the backslash character in a string in JavaScript.

Repeatable params

If you need to match routes with multiple sections like /first/second/third, you should mark a param as repeatable with * (0 or more) and + (1 or more):

const routes = [
  // /:chapters -> matches /one, /one/two, /one/two/three, etc
  { path: '/:chapters+' },
  // /:chapters -> matches /, /one, /one/two, /one/two/three, etc
  { path: '/:chapters*' },
]

This will give you an array of params instead of a string and will also require you to pass an array when using named routes:

// given { path: '/:chapters*', name: 'chapters' },
router.resolve({ name: 'chapters', params: { chapters: [] } }).href
// produces /
router.resolve({ name: 'chapters', params: { chapters: ['a', 'b'] } }).href
// produces /a/b

// given { path: '/:chapters+', name: 'chapters' },
router.resolve({ name: 'chapters', params: { chapters: [] } }).href
// throws an Error because `chapters` is empty

These can also be combined with custom Regexp by adding them after the closing parentheses:

const routes = [
  // only match numbers
  // matches /1, /1/2, etc
  { path: '/:chapters(\\d+)+' },
  // matches /, /1, /1/2, etc
  { path: '/:chapters(\\d+)*' },
]

Optional parameters

You can also mark a parameter as optional by using the ? modifier (0 or 1):

const routes = [
  // will match /users and /users/posva
  { path: '/users/:userId?' },
  // will match /users and /users/42
  { path: '/users/:userId(\\d+)?' },
]

Note that * technically also marks a parameter as optional but ? parameters cannot be repeated.

Debugging

If you need to dig how your routes are transformed into Regexp to understand why a route isn't being matched or, to report a bug, you can use the path ranker tool. It supports sharing your routes through the URL.

© 2013–present Evan You
Licensed under the MIT License.
https://next.router.vuejs.org/guide/essentials/route-matching-syntax