Layouts are enabled by adding <NuxtLayout> to your app.vue:
<template>
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
</template>
To use a layout:
layout property in your page with definePageMeta.name prop of <NuxtLayout>.someLayout becomes some-layout.layouts/default.vue will be used.app.vue instead.<slot />.Add a ~/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.
-| layouts/
---| default.vue
---| custom.vue
Then you can use the custom layout in your page:
<script setup lang="ts">
definePageMeta({
layout: 'custom',
})
</script>
You can directly override the default layout for all pages using the name property of <NuxtLayout>:
<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 |
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>
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>
<template>
<div>
<header>
<slot name="header">
Default header content
</slot>
</header>
<main>
<slot />
</main>
</div>
</template>
<NuxtLayout> within your pages, make sure it is not the root element (or disable layout/page transitions).