---
title: "Layout"
description: "Nuxt Kit provides a set of utilities to help you work with layouts."
links:
  - label: Source
    icon: i-simple-icons-github
    to: https://github.com/nuxt/nuxt/blob/main/packages/kit/src/layout.ts
    size: xs
---

Layouts is used to be a wrapper around your pages. It can be used to wrap your pages with common components, for example, a header and a footer. Layouts can be registered using `addLayout` utility.

## `addLayout`

Register template as layout and add it to the layouts.

::note
In Nuxt 2 `error` layout can also be registered using this utility. In Nuxt 3+ `error` layout [replaced](/docs/4.x/getting-started/error-handling#error-page) with `error.vue` page in project root.
::

### Usage

```ts twoslash
import { addLayout, createResolver, defineNuxtModule } from '@nuxt/kit'

export default defineNuxtModule({
  setup () {
    const { resolve } = createResolver(import.meta.url)

    addLayout({
      src: resolve('templates/custom-layout.ts'),
      filename: 'custom-layout.ts',
    }, 'custom')
  },
})
```

### Type

```ts
function addLayout (layout: NuxtTemplate | string, name: string): void
```

### Parameters

**`layout`**: A template object or a string with the path to the template. If a string is provided, it will be converted to a template object with `src` set to the string value. If a template object is provided, it must have the following properties:

| Property      | Type                                             | Required | Description                                                                                                                                                                      |
| ------------- | ------------------------------------------------ | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `src`         | `string`                                         | `false`  | Path to the template. If `src` is not provided, `getContents` must be provided instead.                                                                                          |
| `filename`    | `string`                                         | `false`  | Filename of the template. If `filename` is not provided, it will be generated from the `src` path. In this case, the `src` option is required.                                   |
| `dst`         | `string`                                         | `false`  | Path to the destination file. If `dst` is not provided, it will be generated from the `filename` path and nuxt `buildDir` option.                                                |
| `options`     | `Record<string, any>`{lang="ts"}                 | `false`  | Options to pass to the template.                                                                                                                                                 |
| `getContents` | `(data) => string \| Promise<string>`{lang="ts"} | `false`  | A function that will be called with the `options` object. It should return a string or a promise that resolves to a string. If `src` is provided, this function will be ignored. |
| `write`       | `boolean`                                        | `false`  | If set to `true`, the template will be written to the destination file. Otherwise, the template will be used only in virtual filesystem.                                         |

**`name`**: The name to register the layout under (e.g., `default`, `custom`, etc.).

### Example

This will register a layout named `custom` that wraps pages with a header and footer.

```ts twoslash
import { addLayout, defineNuxtModule } from '@nuxt/kit'

export default defineNuxtModule({
  setup () {
    addLayout({
      write: true,
      filename: 'my-layout.vue',
      getContents: () => `<template>
  <div>
    <header>My Header</header>
    <slot />
    <footer>My Footer</footer>
  </div>
</template>`,
    }, 'custom')
  },
})
```

You can then use this layout in your pages:

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

<template>
  <div>About Page</div>
</template>
```

::warning
Due to the lack of support for virtual `.vue` files by `@vitejs/plugin-vue`, you can work around this limitation by passing `write: true` to the first argument of `addLayout`.
::
