---
title: "layouts"
head.title: "layouts/"
description: "Nuxt provides a layouts framework to extract common UI patterns into reusable layouts."
navigation.icon: i-ph-folder
---

::tip{icon="i-ph-rocket-launch" color="gray" }
For best performance, components placed in this directory will be automatically loaded via asynchronous import when used.
::

## Enable Layouts

Layouts are enabled by adding [`<NuxtLayout>`](/docs/api/components/nuxt-layout) to your [`app.vue`](/docs/guide/directory-structure/app):

```vue [app.vue]
<template>
  <NuxtLayout>
    <NuxtPage />
  </NuxtLayout>
</template>
```

To use a layout:
- Set a `layout` property in your page with [definePageMeta](/docs/api/utils/define-page-meta).
- Set the `name` prop of `<NuxtLayout>`.

::note
The layout name is normalized to kebab-case, so `someLayout` becomes `some-layout`.
::

::note
If no layout is specified, `layouts/default.vue` will be used.
::

::important
If you only have a single layout in your application, we recommend using [`app.vue`](/docs/guide/directory-structure/app) instead.
::

::important
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 />`.
::

## Default Layout

Add a `~/layouts/default.vue`:

```vue [layouts/default.vue]
<template>
  <div>
    <p>Some default layout content shared across all pages</p>
    <slot />
  </div>
</template>
```

In a layout file, the content of the page will be displayed in the `<slot />` component.

## Named Layout

```bash [Directory Structure]
-| layouts/
---| default.vue
---| custom.vue
```

Then you can use the `custom` layout in your page:

```vue twoslash [pages/about.vue]
<script setup lang="ts">
definePageMeta({
  layout: 'custom'
})
</script>
```

::read-more{to="/docs/guide/directory-structure/pages#page-metadata"}
Learn more about `definePageMeta`.
::

You can directly override the default layout for all pages using the `name` property of [`<NuxtLayout>`](/docs/api/components/nuxt-layout):

```vue [app.vue]
<script setup lang="ts">
// You might choose this based on an API call or logged-in status
const layout = "custom";
</script>

<template>
  <NuxtLayout :name="layout">
    <NuxtPage />
  </NuxtLayout>
</template>
```

If you have a layout in nested directories, the layout's name will be based on its own path directory and filename, with duplicate segments being removed.

File | Layout Name
-- | --
`~/layouts/desktop/default.vue` | `desktop-default`
`~/layouts/desktop-base/base.vue` | `desktop-base`
`~/layouts/desktop/index.vue` | `desktop`

For clarity, we recommend that the layout's filename matches its name:

File | Layout Name
-- | --
`~/layouts/desktop/DesktopDefault.vue` | `desktop-default`
`~/layouts/desktop-base/DesktopBase.vue` | `desktop-base`
`~/layouts/desktop/Desktop.vue` | `desktop`

:link-example{to="/docs/examples/features/layouts"}

## Changing the Layout Dynamically

You can also use the [`setPageLayout`](/docs/api/utils/set-page-layout) helper to change the layout dynamically:

```vue twoslash
<script setup lang="ts">
function enableCustomLayout () {
  setPageLayout('custom')
}
definePageMeta({
  layout: false,
});
</script>

<template>
  <div>
    <button @click="enableCustomLayout">Update layout</button>
  </div>
</template>
```

:link-example{to="/docs/examples/features/layouts"}

## Overriding a Layout on a Per-page Basis

If you are using pages, you can take full control by setting `layout: false` and then using the `<NuxtLayout>` component within the page.

::code-group

```vue [pages/index.vue]
<script setup lang="ts">
definePageMeta({
  layout: false,
})
</script>

<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>
```

::

::important
If you use `<NuxtLayout>` within your pages, make sure it is not the root element (or [disable layout/page transitions](/docs/getting-started/transitions#disable-transitions)).
::
