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| Address | What is shown |
|---|---|
/admin | admin.vue with admin/index.vue inside |
/admin/comments | admin.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.