Vue.js Nation
Join us for the Vue.js Nation Conference 26th & 27th of January 2022
Register for free

Dynamic Pages in Nuxt 3

Nuxt 3 routing builds on the functionality of Nuxt 2 by giving you more ways than ever before to express your dynamic routes. Get more information on new features as well as what got dropped!

Josh Deltener
December 13, 2021

Stay in the Nuxt loop!

Get notified when we release new tutorials, lessons, and other expert Nuxt content.

Dynamic Pages in Nuxt 3

Have you ever needed to represent a set of pages without knowing what their urls are at build time? Nuxt calls these dynamic pages. These special routes are built using a file and folder naming convention.

Nuxt 2

With Nuxt 2 dynamic routes were handled by using an underscore in front of a file or folder.

File: /pages/users/_id.vue
Url:  /users/123

$route.params = { id: "123" }

You can even use both a dynamic folder and a file.

File: /pages/_people/_id.vue
Url:  /developer/123

$route.params = { people: 'developer', id: "123" }

Nuxt 3

Instead of using an underscore _ like Nuxt 2, Nuxt 3 uses brackets [ ]. If you want to move your project over to Nuxt 3 you'll have to migrate dynamic pages to the new way.

Here is the first example using the new method. We just replaced the underscore with brackets around the filename.

File: /pages/users/[id].vue
Url:  /users/123

$route.params = { id: '123' }

And as expected, the second example is similar.

File: /pages/[people]/[id].vue
Url:  /developer/123

$route.params = { people: 'developer', id: '123' }

Now let's start to get a little crazy. Using brackets allows you to also match both static and dynamic text within a route!

File: /pages/person-[name]/index.vue
Url:  /person-spongebob/

$route.params = { name: 'spongebob' }

And just like example two, you can even do partial matches on child-routes as well.

File: /pages/person-[name]/lives-[area].vue
Url:  /person-spongebob/lives-ocean/

$route.params = { name: 'spongebob', lives: 'ocean'}

Nuxt 3 even allows you to do multiple dynamic matching!

File: /pages/person-[name]-[color]/lives-[area]-[city].vue
Url:  /person-spongebob-yellow/lives-ocean-bikinibottom/

$route.params = { 
  name: 'spongebob', 
  color: 'yellow', 
  area: 'ocean', 
  city: 'bikinibottom'
}

There is one more surprise, Nuxt 3 also lets you have catchall files that can match any number of arguments! Anything that matches after the folder name will be added to an array using the key name of your filename.

File: /pages/person/[...slugs].vue

Url:  /person/spongebob/123/abc
$route.params = { slugs: ['spongebob', '123', 'abc' ] }

Url: /person/
$route.params = ''

As you can see, the new Nuxt 3 routing matcher is very powerful! Thankfully, since it can do everything Nuxt 2 does (and more), migrating should be fairly straight forward.

Josh Deltener
Josh is a true Nuxt Master. He has over 30 years of development experience and currently works as director of front-end technology at RealTruck. He is also a Nuxt ambassador and contributor.