Defining Nested Routes with Vue Router
Tags: vue, webdev, programming, javascript
Published: 2021-01-25 23:19:10

**Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62**

**Subscribe to my email list now at http://jauyeung.net/subscribe/**

Vue.js is an easy to use web app framework that we can use to develop interactive front end apps.

In this article, we’ll look at how to define nested routes with Vue Router.

Why do we Need Nested Routes?
=============================

We need nested routes to organize routes where components are nested multiple levels deep.

For example, we have to find a way to organize routes like:

```
/user/bar/profile                       
/user/bar/posts
```

into one coherent place.

Defining Nested Routes
======================

We can define nested routes by adding a `children` array in the route entry, and then in the parent route’s template we have to add `router-view` to display the children routes.

For example, we can write the following:

`src/index.js` :

```
const Profile = { template: "<p>{{$route.params.user}}'s profile</p>" };  
const Posts = { template: "<p>{{$route.params.user}}'s posts</p>" };  
const User = {  
  template: `  
    <div>  
      <p>user - {{$route.params.user}}</p>  
      <router-view></router-view>  
    </div>  
`  
};  
const routes = [  
  {  
    path: "/user/:user",  
    component: User,  
    children: [  
      { path: "posts", component: Posts },  
      { path: "profile", component: Profile }  
    ]  
  }  
];

const router = new VueRouter({  
  routes  
});

new Vue({  
  el: "#app",  
  router  
});
```

`index.html` :

```
<!DOCTYPE html>  
<html>  
  <head>  
    <title>App</title>  
    <meta charset="UTF-8" />  
    <script src="[https://unpkg.com/vue/dist/vue.js](https://unpkg.com/vue/dist/vue.js)"></script>  
    <script src="[https://unpkg.com/vue-router/dist/vue-router.js](https://unpkg.com/vue-router/dist/vue-router.js)"></script>  
  </head>  
  <body>  
    <div id="app">  
      <div>  
        <router-link to="/user/foo">Foo User</router-link>  
        <router-link to="/user/foo/posts">Foo Post</router-link>  
        <router-link to="/user/foo/profile">Foo Profile</router-link>  
      </div>  
      <router-view></router-view>  
    </div>  
    <script src="src/index.js"></script>  
  </body>  
</html>
```

In the code above, we have:

```
const routes = [  
  {  
    path: "/user/:user",  
    component: User,  
    children: [  
      { path: "posts", component: Posts },  
      { path: "profile", component: Profile }  
    ]  
  }  
];
```

to define the child routes.

The `Posts` and `Profile` components are like any component we defined as usual.

However, the `User` component has the `router-view` to display them content of the `Posts` and `Profile` components.

In the template, we have 3 router links to go to the root and child routes:

```
<router-link to="/user/foo">Foo User</router-link>  
<router-link to="/user/foo/posts">Foo Post</router-link>  
<router-link to="/user/foo/profile">Foo Profile</router-link>
```

Then we should see:

```
Foo User Foo Post Foo Profile  
user - foofoo's posts
```

when we go to `/#/user/foo/posts` or click on `Foo Post` .

And we should see:

```
Foo User Foo Post Foo Profileuser - foofoo's profile
```

when we go to `/#/user/foo/profile` or click on `Foo Profile`.

When we go to `/#/user/foo` or click on `Foo User` , we see:

```
Foo User Foo Post Foo Profileuser - foo
```

Any nested path that starts with `/` will be treated as the root path. This lets us use component nesting without having to use a nested URL.

Also, the parent and child routes all have access to the same route parameters.

For example, we can add a `UserHome` component and a route for it to the example above as follows:

`src/index.js` :

```
const Profile = { template: "<p>{{$route.params.user}}'s profile</p>" };  
const Posts = { template: "<p>{{$route.params.user}}'s posts</p>" };  
const UserHome = { template: "<p>{{$route.params.user}} home</p>" };  
const User = {  
  template: `  
    <div>  
      <p>user - {{$route.params.user}}</p>  
      <router-view></router-view>  
    </div>`  
};  
const routes = [  
  {  
    path: "/user/:user",  
    component: User,  
    children: [  
      { path: "", component: UserHome },  
      { path: "posts", component: Posts },  
      { path: "profile", component: Profile }  
    ]  
  }  
];

const router = new VueRouter({  
  routes  
});

new Vue({  
  el: "#app",  
  router  
});
```

`index.html` :

```
<!DOCTYPE html>  
<html>  
  <head>  
    <title>App</title>  
    <meta charset="UTF-8" />  
    <script src="https://unpkg.com/vue/dist/vue.js"></script>  
    <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>  
  </head>  
  <body>  
    <div id="app">  
      <div>  
        <router-link to="/user/foo">Foo User</router-link>  
        <router-link to="/user/foo/posts">Foo Post</router-link>  
        <router-link to="/user/foo/profile">Foo Profile</router-link>  
      </div>  
      <router-view></router-view>  
    </div>  
    <script src="src/index.js"></script>  
  </body>  
</html>
```

Now when we go to `/user/foo` or click on `Foo User` , we see:

```
Foo User Foo Post Foo Profileuser - foofoo home
```

Everything else remains the same.

Conclusion
==========

We can add nested routes to our routes by adding a `children` property with an array of routes.

Then we have to add `router-view` to the parent route so that we can see the content of the child routes.

The parent and child routes all have access to the same route parameters.