app.vue and NuxtPage
app/app.vue is the root component: Nuxt starts building every page of the site from it. Whatever you write in it is visible at every address, and the <NuxtPage /> component shows the page that matches the current address.
The file after creating a project
The file app/app.vue already exists in the project:
<!-- app/app.vue -->
<template>
<div>
<NuxtRouteAnnouncer />
<NuxtWelcome />
</div>
</template><NuxtWelcome /> is the welcome page you saw at http://localhost:3000. <NuxtRouteAnnouncer /> tells screen readers the title of the new page after navigation; keep it.
Your own root component
Replace the file content:
<!-- app/app.vue -->
<template>
<div>
<NuxtRouteAnnouncer />
<h1>My blog</h1>
</div>
</template>Save the file and the page reloads by itself, showing the heading "My blog". While the project has no app/pages/ folder, app.vue is the only page: every address shows the same heading.
Showing pages
To give the site separate pages, create the first one with a command:
npx nuxi add page indexThe command creates app/pages/index.vue. Replace its content:
<!-- app/pages/index.vue -->
<template>
<section>
<h2>Home</h2>
<p>Latest posts will be here.</p>
</section>
</template>Now tell app.vue where to show pages:
<!-- app/app.vue -->
<template>
<div>
<NuxtRouteAnnouncer />
<header>My blog</header>
<main>
<NuxtPage />
</main>
</div>
</template>Nuxt puts the page component for the current address in place of <NuxtPage />. At / you see the "My blog" header and the "Home" section below it. If you know Vue Router, <NuxtPage /> plays the same role as <RouterView />.
What belongs in app.vue
| Fits | Does not fit |
|---|---|
<NuxtPage /> and the layout wrapper | The content of individual pages |
Global title settings with useHead | Fetching data for one page |
| Code the whole app needs | Header and footer: layouts exist for them |
The header stays here for simplicity; in the layouts lesson it moves to its own file.
Common mistake
After creating files in app/pages/, it is easy to forget about app.vue. If it still contains <NuxtWelcome /> or simply has no <NuxtPage />, the pages do not appear: every address shows the same app.vue content. As soon as the project has pages, app.vue must contain <NuxtPage />.