Skip to content
← All questions
🌱 Beginner

What are Nuxt layouts and how do they work?

💚 Nuxt🧩 Components

Layouts are wrapper components that surround your pages. They define shared UI like headers, footers, and sidebars. Instead of repeating that structure in every page, you define it once in a layout and let Nuxt wrap your pages automatically.

Diagram showing NuxtLayout wrapping page content via slot

Default layout

Create layouts/default.vue. Every page uses it automatically unless told otherwise:

vue
<!-- layouts/default.vue -->
<template>
  <div>
    <AppHeader />
    <main>
      <slot />
    </main>
    <AppFooter />
  </div>
</template>

The <slot /> is where the page content renders.

Custom layouts

Create additional layouts for different sections of your app:

vue
<!-- layouts/admin.vue -->
<template>
  <div class="admin-layout">
    <AdminSidebar />
    <main class="admin-content">
      <slot />
    </main>
  </div>
</template>
vue
<!-- layouts/auth.vue -->
<template>
  <div class="auth-layout">
    <slot />
  </div>
</template>

Assigning a layout to a page

Use definePageMeta to pick a layout:

vue
<!-- pages/dashboard.vue -->
<script setup>
definePageMeta({
  layout: 'admin'
})
</script>

<template>
  <h1>Dashboard</h1>
</template>
vue
<!-- pages/login.vue -->
<script setup>
definePageMeta({
  layout: 'auth'
})
</script>

<template>
  <LoginForm />
</template>

Pages without definePageMeta({ layout }) use the default layout.

Disabling the layout

Some pages need no layout at all:

vue
<!-- pages/embed.vue -->
<script setup>
definePageMeta({
  layout: false
})
</script>

<template>
  <WidgetEmbed />
</template>

Changing layout dynamically

Use setPageLayout to switch layouts at runtime:

vue
<script setup>
function switchToAdmin() {
  setPageLayout('admin')
}
</script>

<template>
  <button @click="switchToAdmin">Enter admin mode</button>
</template>

Layout transitions

Add transitions when switching between layouts:

ts
// nuxt.config.ts
export default defineNuxtConfig({
  app: {
    layoutTransition: { name: 'layout', mode: 'out-in' }
  }
})
css
/* assets/css/main.css */
.layout-enter-active,
.layout-leave-active {
  transition: opacity 0.3s;
}

.layout-enter-from,
.layout-leave-to {
  opacity: 0;
}

Using NuxtLayout in app.vue

If you have an app.vue, you need <NuxtLayout> to enable layouts:

vue
<!-- app.vue -->
<template>
  <NuxtLayout>
    <NuxtPage />
  </NuxtLayout>
</template>

Without <NuxtLayout>, layouts are ignored even if pages declare them.

Layout directory structure

layouts/
├── default.vue    ← used by all pages unless overridden
├── admin.vue      ← pages opt in via definePageMeta
└── auth.vue       ← minimal layout for login/register

When to use layouts vs components

NeedUse
Shared header/footer/sidebar across many pagesLayout
Wrapper that only a few components useRegular component
Different structure for public vs admin pagesMultiple layouts
No wrapper at all (embed, widget)layout: false

See also: How does Nuxt handle state management? · How do slots work?

References

Released under the MIT License.