Suggest an editImprove this articleRefine the answer for “What are layouts in Nuxt?”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**Nuxt layouts** are Vue templates in the `layouts/` directory that wrap pages with shared UI like headers and footers. `layouts/default.vue` applies to every page automatically. For a different layout, add `definePageMeta({ layout: 'name' })` to the page. Page content renders inside `<slot />`. **Key:** layouts keep shared UI out of individual page files.Shown above the full answer for quick recall.Answer (EN)Image**Layouts in Nuxt** are reusable Vue templates that wrap page content with shared UI elements like headers, sidebars, or footers. The page renders inside the layout's `<slot />`. ## Theory ### TL;DR - A layout is the building shell: walls stay the same while the furniture (page content) changes per room. - Pages focus on content; layouts own the persistent frame around it. - If more than 2 pages share the same UI shell, a layout saves you from copy-pasting headers across files. - No layout specified? Nuxt falls back to `layouts/default.vue` automatically. ### Quick example ```vue <!-- layouts/default.vue --> <template> <div class="app"> <nav>Global Nav</nav> <main> <slot /> <!-- page content renders here --> </main> <footer>© 2024</footer> </div> </template> <!-- pages/about.vue (no meta needed, default applies) --> <template> <p>About us</p> </template> <!-- Output: nav + "About us" + footer --> ``` The `about.vue` page never knows about the nav or footer. It renders its own content, and the layout wraps it. ### Key difference Layouts separate persistent UI from page-specific content via `<slot />`. A page like `/about` renders inside `default.vue` without any extra code. A page like `/admin/orders` opts into `admin.vue` with one line in `definePageMeta`. That is why pages stay slim and focused on their own data. ### When to use - Shared header and footer on all pages: create `layouts/default.vue`. - Admin section with a sidebar: `layouts/admin.vue` + `definePageMeta({ layout: 'admin' })` on each admin page. - Landing pages vs app pages: `layouts/landing.vue` for marketing, `layouts/app.vue` for authenticated users. - Page with no wrapper at all (fullscreen canvas, bare route): `definePageMeta({ layout: false })`. ### How Nuxt resolves a layout At build time, Nuxt scans `layouts/` and registers each file by name. During navigation it checks `definePageMeta` on the target page. If nothing is set, it falls back to `default`. If `default.vue` does not exist, the page renders without any wrapper. I once watched a developer delete `default.vue` thinking it was unused. Every page lost its nav immediately. Worth keeping in mind. ### Common mistakes **1. Forgetting `layout: false` on bare pages.** Any page without a layout setting gets `default.vue` applied. A fullscreen canvas or a bare route will automatically inherit the header and footer. ```vue <script setup> definePageMeta({ layout: false }) </script> ``` **2. Setting layout in a variable instead of `definePageMeta`.** ```vue <!-- Wrong: ignored at runtime --> <script setup> const layout = 'admin' // does nothing </script> <!-- Right --> <script setup> definePageMeta({ layout: 'admin' }) </script> ``` Only `definePageMeta` registers the layout choice. Variables in `<script setup>` are not read for this. **3. Putting `<slot />` before the header.** ```vue <!-- Wrong: page content renders above the nav --> <template> <slot /> <header>Nav</header> </template> <!-- Right --> <template> <header>Nav</header> <slot /> <footer>Footer</footer> </template> ``` Order in the template equals order on screen. Slot position is content position. ### Real-world usage - Blog or docs site: `layouts/docs.vue` with a sidebar TOC for all `/blog/*` pages. - E-commerce checkout: `layouts/checkout.vue` with a progress bar, no main nav. - Admin panel: `layouts/admin.vue` with a drawer for all `/admin/*` routes. - Multi-tenant SaaS: different layout per tenant, switched via middleware. ### Follow-up questions **Q:** What happens if `layouts/default.vue` does not exist? **A:** The page renders bare, with no wrapper. Nuxt does not throw an error. **Q:** Can a layout access data from the page inside it? **A:** Not directly. Use `useState` or `useRoute()` for state shared between layout and page. **Q:** What is the difference between `layout: false` and `layout: 'none'`? **A:** Both skip the layout. In Nuxt 3.6+, `false` is the preferred alias. Use it. **Q:** How do you nest layouts? **A:** Not natively supported. Use `<NuxtLayout>` inside a parent layout's `<slot />` as a workaround. **Q:** During SSR, if the layout's data fetch fails, what happens to the page? **A:** The page renders inside the layout's error boundary. Use `error.vue` as a fallback layout, or wrap async layout data in `<ClientOnly>`. ## Examples ### Basic: default layout with no configuration ```vue <!-- layouts/default.vue --> <template> <div class="page-wrapper"> <header>My App</header> <slot /> <footer>My Footer</footer> </div> </template> <!-- pages/home.vue --> <template> <h1>Welcome home</h1> </template> <!-- Output: header + "Welcome home" + footer, no extra config needed --> ``` Every page picks up the default layout automatically. No `definePageMeta` required. ### Intermediate: dashboard layout shared across admin pages ```vue <!-- layouts/dashboard.vue --> <template> <div class="dashboard"> <aside class="sidebar"> <NuxtLink to="/dashboard/orders">Orders</NuxtLink> <NuxtLink to="/dashboard/products">Products</NuxtLink> </aside> <main class="content"> <slot /> </main> </div> </template> <!-- pages/dashboard/orders.vue --> <script setup> definePageMeta({ layout: 'dashboard' }) const { data: orders } = await useFetch('/api/orders') </script> <template> <ul> <li v-for="order in orders" :key="order.id"> Order #{{ order.id }} - ${{ order.total }} </li> </ul> </template> ``` Both `/dashboard/orders` and `/dashboard/products` share the same sidebar. Navigating between them does not re-render the layout. Only the `<slot />` content swaps.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.