Layouts wrap your pages to provide consistent structure like headers, footers, and navigation.
Default Layout
vue<!-- layouts/default.vue --> <template> <div class="layout"> <AppHeader /> <main class="content"> <slot /> <!-- Page content goes here --> </main> <AppFooter /> </div> </template> <style scoped> .layout { min-height: 100vh; display: flex; flex-direction: column; } .content { flex: 1; padding: 2rem; } </style>
Using Layouts in App
vue<!-- app.vue --> <template> <NuxtLayout> <NuxtPage /> </NuxtLayout> </template>
Custom Layouts
vue<!-- layouts/dashboard.vue --> <template> <div class="dashboard-layout"> <Sidebar /> <div class="dashboard-main"> <DashboardHeader /> <slot /> </div> </div> </template>
Use in page:
vue<!-- pages/dashboard/index.vue --> <script setup> definePageMeta({ layout: 'dashboard' }) </script> <template> <h1>Dashboard Home</h1> </template>
Dynamic Layouts
vue<script setup> const route = useRoute() // Change layout based on condition definePageMeta({ layout: false // Disable auto layout }) const layoutName = computed(() => { return route.meta.isAdmin ? 'admin' : 'default' }) </script> <template> <NuxtLayout :name="layoutName"> <h1>Dynamic Layout Page</h1> </NuxtLayout> </template>
Layout Transitions
vue<!-- app.vue --> <template> <NuxtLayout> <NuxtPage /> </NuxtLayout> </template> <style> .layout-enter-active, .layout-leave-active { transition: opacity 0.3s; } .layout-enter-from, .layout-leave-to { opacity: 0; } </style>
typescript// nuxt.config.ts export default defineNuxtConfig({ app: { layoutTransition: { name: 'layout', mode: 'out-in' } } })
Named Slots in Layouts
vue<!-- layouts/with-sidebar.vue --> <template> <div class="layout-with-sidebar"> <aside class="sidebar"> <slot name="sidebar" /> </aside> <main class="main"> <slot /> </main> </div> </template>
vue<!-- pages/docs.vue --> <script setup> definePageMeta({ layout: 'with-sidebar' }) </script> <template> <NuxtLayout> <template #sidebar> <nav> <NuxtLink to="/docs/intro">Introduction</NuxtLink> <NuxtLink to="/docs/setup">Setup</NuxtLink> </nav> </template> <h1>Documentation Content</h1> </NuxtLayout> </template>