Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Nested routes

A nested route is a page shown inside another page. The parent sets the shared part of a section (a heading, tabs), and the child page changes with the address. This suits sections with tabs, such as a blog admin area.

How the files are laid out

Nesting appears when a file and a folder with the same name sit side by side:

app/pages/
├── admin.vue
└── admin/
    ├── index.vue
    └── comments.vue
AddressWhat is shown
/adminadmin.vue with admin/index.vue inside
/admin/commentsadmin.vue with admin/comments.vue inside

The parent page

The file app/pages/admin.vue from the layouts lesson becomes the parent. Add tabs and <NuxtPage /> to it:

<!-- app/pages/admin.vue -->
<script setup lang="ts">
definePageMeta({
  layout: 'admin'
})
</script>
 
<template>
  <section>
    <h2>Dashboard</h2>
    <nav>
      <NuxtLink to="/admin">Posts</NuxtLink>
      <NuxtLink to="/admin/comments">Comments</NuxtLink>
    </nav>
    <NuxtPage />
  </section>
</template>

<NuxtPage /> inside a page works like the one in app.vue, except it shows the child page.

Child pages

Create two files:

<!-- app/pages/admin/index.vue -->
<template>
  <div>
    <h3>Posts</h3>
    <p>A list of posts to edit will be here.</p>
  </div>
</template>
<!-- app/pages/admin/comments.vue -->
<template>
  <div>
    <h3>Comments</h3>
    <p>New comments will be here.</p>
  </div>
</template>

Open /admin and switch tabs: the "Dashboard" heading and the tabs stay in place, only the lower part changes.

Parameters in child pages

A child page can be dynamic, for example app/pages/admin/[id].vue for editing a post at /admin/5. The parent also sees the parameter through useRoute().params.id.

When you do not need nesting

The post list app/pages/posts/index.vue and the post page app/pages/posts/[id].vue are separate pages. There is no app/pages/posts.vue for them, so each one takes the whole space inside the layout. That is correct: the list and the post have no shared part.

Common mistake

If you create app/pages/posts.vue next to the app/pages/posts/ folder, every page in the folder becomes its child. When posts.vue has no <NuxtPage />, the addresses /posts/1 and /posts/new show only the content of posts.vue. Either add <NuxtPage /> to the parent, or move its content to posts/index.vue if nesting was not intended.

Thanks for reading!

Donate to the site — we work hard for you.