37% OFF during Black Friday at Mastering Nuxt.

layouts

Nuxt provides a layouts framework to extract common UI patterns into reusable layouts.
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> to your app.vue:

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

To use a layout:

  • Set a layout property in your page with definePageMeta.
  • Set the name prop of <NuxtLayout>.
The layout name is normalized to kebab-case, so someLayout becomes some-layout.
If no layout is specified, layouts/default.vue will be used.
If you only have a single layout in your application, we recommend using app.vue instead.
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:

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

Directory Structure
-| layouts/
---| default.vue
---| custom.vue

Then you can use the custom layout in your page:

pages/about.vue
<script setup lang="ts">
definePageMeta
({
layout
: 'custom'
}) </script>
Learn more about definePageMeta.

You can directly override the default layout for all pages using the name property of <NuxtLayout>:

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.

FileLayout Name
~/layouts/desktop/default.vuedesktop-default
~/layouts/desktop-base/base.vuedesktop-base
~/layouts/desktop/index.vuedesktop

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

FileLayout Name
~/layouts/desktop/DesktopDefault.vuedesktop-default
~/layouts/desktop-base/DesktopBase.vuedesktop-base
~/layouts/desktop/Desktop.vuedesktop
Read and edit a live example in Docs > Examples > Features > Layouts.

Changing the Layout Dynamically

You can also use the setPageLayout helper to change the layout dynamically:

<script setup lang="ts">
function 
enableCustomLayout
() {
setPageLayout
('custom')
}
definePageMeta
({
layout
: false,
}); </script> <template> <
div
>
<
button
@
click
="
enableCustomLayout
">Update layout</
button
>
</
div
>
</template>
Read and edit a live example in 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.

<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>
If you use <NuxtLayout> within your pages, make sure it is not the root element (or disable layout/page transitions).