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
Nuxt 3

Mastering Nuxt 3 course is here!

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

Click here to view the Nuxt 3 course

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" }
Cyber Monday

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', area: '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.

Cyber Monday
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.

Follow MasteringNuxt on