2021-10-11 12:57:54 +00:00
---
2022-10-06 09:15:30 +00:00
navigation.icon: IconDirectory
title: "layouts"
description: "Nuxt provides a layouts framework to extract common UI patterns into reusable layouts."
2022-11-21 15:51:39 +00:00
head.title: "layouts/"
2021-10-11 12:57:54 +00:00
---
2021-06-08 21:44:30 +00:00
2022-08-13 07:27:04 +00:00
# Layouts Directory
2021-06-30 16:32:22 +00:00
Nuxt provides a customizable layouts framework you can use throughout your application, ideal for extracting common UI or code patterns into reusable layout components.
2023-07-07 16:24:09 +00:00
Layouts are placed in the [`layouts/` directory ](/docs/guide/directory-structure/layouts ) and will be automatically loaded via asynchronous import when used. Layouts are used by adding `<NuxtLayout>` to your `app.vue` , and either setting a `layout` property as part of your page metadata (if you are using the `~/pages` integration), or by manually specifying it as a prop to `<NuxtLayout>` . (**Note**: The layout name is normalized to kebab-case, so `someLayout` becomes `some-layout` .)
2021-06-30 16:32:22 +00:00
2022-11-16 10:04:28 +00:00
If you only have a single layout in your application, we recommend using [app.vue ](/docs/guide/directory-structure/app ) instead.
2021-06-30 16:32:22 +00:00
2022-03-14 10:47:24 +00:00
::alert{type=warning}
2022-04-07 10:59:40 +00:00
Unlike other components, your layouts must have a single root element to allow Nuxt to apply transitions between layout changes - and this root element cannot be a `<slot />` .
2022-03-14 10:47:24 +00:00
::
2022-08-13 07:27:04 +00:00
## Enabling the Default Layout
2021-06-30 16:32:22 +00:00
2022-06-27 12:08:19 +00:00
Add a `~/layouts/default.vue` :
2021-06-30 16:32:22 +00:00
2022-06-27 12:08:19 +00:00
```vue [layouts/default.vue]
2021-06-30 16:32:22 +00:00
< template >
< div >
2022-06-27 12:08:19 +00:00
Some default layout shared across all pages
2021-06-30 16:32:22 +00:00
< slot / >
< / div >
< / template >
```
2022-06-27 12:08:19 +00:00
In a layout file, the content of the layout will be loaded in the `<slot />` , rather than using a special component.
2021-06-30 16:32:22 +00:00
2022-06-27 12:08:19 +00:00
If you use a `app.vue` you will also need to add `<NuxtLayout>` :
```vue [app.vue]
2022-03-14 10:47:24 +00:00
< template >
2022-06-27 12:08:19 +00:00
< NuxtLayout >
some page content
2022-03-14 10:47:24 +00:00
< / NuxtLayout >
< / template >
```
2022-08-13 07:27:04 +00:00
## Setting Another Layout
2022-03-14 10:47:24 +00:00
```bash
-| layouts/
2022-06-27 12:08:19 +00:00
---| default.vue
2022-03-14 10:47:24 +00:00
---| custom.vue
```
2022-06-27 12:08:19 +00:00
You can directly override the default layout like this:
```vue{}[app.vue]
2023-07-18 10:31:45 +00:00
< script setup lang = "ts" >
// You might choose this based on an API call or logged-in status
const layout = "custom";
< / script >
2022-06-27 12:08:19 +00:00
< template >
< NuxtLayout :name = "layout" >
< NuxtPage / >
< / NuxtLayout >
< / template >
```
Alternatively, you can override the default layout per-page like this:
::code-group
2022-03-14 10:47:24 +00:00
```vue{}[pages/index.vue]
2021-06-30 16:32:22 +00:00
< script >
2022-08-18 08:40:24 +00:00
// This will work in both `<script setup>` and `<script>`
2022-01-17 18:27:23 +00:00
definePageMeta({
2021-06-30 16:32:22 +00:00
layout: "custom",
2022-01-17 18:27:23 +00:00
});
2021-06-30 16:32:22 +00:00
< / script >
```
2022-05-31 22:34:41 +00:00
```vue{}[app.vue]
< template >
< NuxtLayout >
< NuxtPage / >
< / NuxtLayout >
< / template >
```
2022-04-25 16:54:20 +00:00
```vue [layouts/custom.vue]
< template >
< div >
2022-06-27 12:08:19 +00:00
Some *custom* layout
< slot / >
2022-04-25 16:54:20 +00:00
< / div >
< / template >
```
2022-06-27 12:08:19 +00:00
```vue [layouts/default.vue]
2021-06-30 16:32:22 +00:00
< template >
2022-06-08 19:53:39 +00:00
< div >
2022-06-27 12:08:19 +00:00
A *default* layout
< slot / >
2022-06-08 19:53:39 +00:00
< / div >
2021-06-30 16:32:22 +00:00
< / template >
```
2021-10-21 10:14:40 +00:00
2022-04-25 16:54:20 +00:00
::
2022-06-27 12:08:19 +00:00
::alert{type=info}
2022-11-16 10:04:28 +00:00
Learn more about [defining page meta ](/docs/guide/directory-structure/pages#page-metadata ).
2022-06-08 19:53:39 +00:00
::
2022-08-13 07:27:04 +00:00
## Changing the Layout Dynamically
2021-10-21 10:14:40 +00:00
2022-01-17 18:27:23 +00:00
You can also use a ref or computed property for your layout.
2021-10-21 10:14:40 +00:00
```vue
2023-07-18 10:31:45 +00:00
< script setup lang = "ts" >
2022-01-17 18:27:23 +00:00
function enableCustomLayout () {
2022-08-31 08:02:48 +00:00
setPageLayout('custom')
2022-01-17 18:27:23 +00:00
}
definePageMeta({
2022-01-26 11:56:24 +00:00
layout: false,
2022-01-17 18:27:23 +00:00
});
2021-10-21 10:14:40 +00:00
< / script >
2023-07-18 10:31:45 +00:00
< template >
< div >
< button @click =" enableCustomLayout " > Update layout</ button >
< / div >
< / template >
2021-10-21 10:14:40 +00:00
```
2022-04-09 09:25:13 +00:00
2023-06-27 11:27:11 +00:00
::LinkExample{link="/docs/examples/features/layouts"}
2022-10-25 09:33:09 +00:00
::
2022-06-27 12:08:19 +00:00
2022-08-13 07:27:04 +00:00
## Overriding a Layout on a Per-page Basis
2022-06-27 12:08:19 +00:00
If you are using the `~/pages` integration, you can take full control by setting `layout: false` and then using the `<NuxtLayout>` component within the page.
::code-group
```vue [pages/index.vue]
2023-07-18 10:31:45 +00:00
< script setup lang = "ts" >
definePageMeta({
layout: false,
});
< / script >
2022-06-27 12:08:19 +00:00
< template >
< div >
< NuxtLayout name = "custom" >
< template #header > Some header template content. </ template >
The rest of the page
< / NuxtLayout >
< / div >
< / template >
```
```vue [layouts/custom.vue]
< template >
< div >
< header >
< slot name = "header" >
Default header content
< / slot >
< / header >
< main >
< slot />
< / main >
< / div >
< / template >
```
::
::alert{type=warning}
If you use `<NuxtLayout>` within your pages, make sure it is not the root element (or disable layout/page transitions).
::