app.vue — The App Entry

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.

4 min read Level 1/5 #nuxt#app#entry
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 NuxtLoadingIndicator for 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 →