Where Layouts and Pages Mount
app.vue — The App Entry
app.vue is Nuxt's single entry component. It typically wraps the page slot in a layout and mounts the router outlet.
What you'll learn
- Read the default app.vue
- Add a NuxtLayout wrapper around NuxtPage
- Understand the page slot
app.vue is the one component that always renders. It sits above pages and layouts and is the only place truly shared across every route.
The Default app.vue
A fresh Nuxt project starts with the simplest possible entry:
<template>
<NuxtPage />
</template> NuxtPage is the router outlet — Nuxt swaps in the matched page component as the user navigates. If you delete app.vue, Nuxt falls back to an internal default that does essentially this.
Adding a Layout Wrapper
To share chrome across routes, wrap NuxtPage in NuxtLayout:
<template>
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
</template> NuxtLayout reads each page’s layout meta (defaulting to layouts/default.vue) and renders that around the page.
What Belongs in app.vue
Treat app.vue like a global shell — content here renders on every route, even error pages. Good candidates:
- A
NuxtLoadingIndicatorfor top-of-page progress bars. - Toast notification mount points.
- Global error boundaries via
NuxtErrorBoundary.
<template>
<NuxtLoadingIndicator color="#10b981" />
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
</template> Resist the urge to put route-specific markup here — that is what layouts and pages are for.
Pages — File-Based Routing →