Skip to content
This repository was archived by the owner on Apr 6, 2023. It is now read-only.
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
138 changes: 84 additions & 54 deletions docs/content/2.guide/3.directory-structure/6.layouts.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,53 +8,65 @@ head.title: Layouts directory

Nuxt provides a customizable layouts framework you can use throughout your application, ideal for extracting common UI or code patterns into reusable layout components.

Layouts are placed in the `layouts/` directory and will be automatically loaded via asynchronous import when used. Layouts are used by setting a `layout` property as part of your page metadata (if you are using the `~/pages` integration), or by using the `<NuxtLayout>` component. (**Note**: The layout name is normalized to kebab-case, so `someLayout` becomes `some-layout`.)
Layouts are placed in the `layouts/` directory 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`.)

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

::alert{type=warning}
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 />`.
::

## Example: Enabling layouts with `app.vue`
## Enabling the default layout

```bash
-| layouts/
---| custom.vue
-| app.vue
```
Add a `~/layouts/default.vue`:

In your layout files, you'll need to use `<slot />` to define where the content of your layout will be loaded. For example:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Explaining about <slot /> was nice why you think should be removed here?


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

Here's how you might use that layout in `app.vue`:
In a layout file, the content of the layout will be loaded in the `<slot />`, rather than using a special component.

```vue{}[app.vue]
If you use a `app.vue` you will also need to add `<NuxtLayout>`:

```vue [app.vue]
<template>
<NuxtLayout name="custom">
Hello world!
<NuxtLayout>
some page content
</NuxtLayout>
</template>
```

## Example: setting the layout with `~/pages`
## Setting another layout

```bash
-| layouts/
---| default.vue
---| custom.vue
-| pages/
---| index.vue
```

You can set your layout within your page components like this:
You can directly override the default layout like this:

```vue{}[app.vue]
<template>
<NuxtLayout :name="layout">
<NuxtPage />
</NuxtLayout>
</template>

<script setup>
// You might choose this based on an API call or logged-in status
const layout = "custom";
</script>
```

Alternatively, you can override the default layout per-page like this:

::code-group

```vue{}[pages/index.vue]
<script>
Expand All @@ -65,8 +77,6 @@ definePageMeta({
</script>
```

And in your `app.vue` you need to wrap the `NuxtPage` component with the `NuxtLayout` component.

```vue{}[app.vue]
<template>
<NuxtLayout>
Expand All @@ -75,56 +85,31 @@ And in your `app.vue` you need to wrap the `NuxtPage` component with the `NuxtLa
</template>
```

::alert{type=info}
Learn more about [defining page meta](/guide/directory-structure/pages#page-metadata).
::

## Example: manual control with `~/pages`

Even if you are using the `~/pages` integration, you can take full control by using the `<NuxtLayout>` component (which is globally available throughout your application), by setting `layout: false`.

::code-group

```vue [layouts/custom.vue]
<template>
<div>
<header>
<slot name="header">
Default header content
</slot>
</header>
<main>
<slot />
</main>
Some *custom* layout
<slot />
</div>
</template>
```

```vue [pages/index.vue]
```vue [layouts/default.vue]
<template>
<div>
<NuxtLayout name="custom">
<template #header> Some header template content. </template>

The rest of the page
</NuxtLayout>
A *default* layout
<slot />
</div>
</template>

<script setup>
definePageMeta({
layout: false,
});
</script>
```

::

::alert{type=warning}
If you use `<NuxtLayout>` within your pages, make sure it is not the root element (or disable layout/page transitions).
::alert{type=info}
Learn more about [defining page meta](/guide/directory-structure/pages#page-metadata).
::

## Example: changing the layout
## Changing the layout dynamically

You can also use a ref or computed property for your layout.

Expand All @@ -147,3 +132,48 @@ definePageMeta({
```

:LinkExample{link="/examples/routing/layouts"}

## Overriding a layout on a per-page basis

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.
Comment thread
danielroe marked this conversation as resolved.

::code-group

```vue [pages/index.vue]
<template>
<div>
<NuxtLayout name="custom">
<template #header> Some header template content. </template>

The rest of the page
</NuxtLayout>
</div>
</template>

<script setup>
definePageMeta({
layout: false,
});
</script>
```

```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).
::