# layouts

> Каталог layouts/ — общие каркасы интерфейса в виде переиспользуемых лейаутов.

<tip icon="i-lucide-rocket">

Компоненты из этого каталога подгружаются лениво, когда лейаут реально используется.

</tip>

## Включение лейаутов

Лейауты подключаются добавлением [`<NuxtLayout>`](/docs/3.x/api/components/nuxt-layout) в [`app.vue`](/docs/3.x/directory-structure/app):

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

Чтобы использовать лейаут:

- Задайте свойство `layout` на странице через [definePageMeta](/docs/3.x/api/utils/define-page-meta).
- Установите свойство `name` для `<NuxtLayout>`.
- Задайте свойство `appLayout` в правилах маршрутов (route rules).

<note>

Имя лейаута нормализуется до kebab-case, поэтому `someLayout` становится `some-layout`.

</note>

<note>

Если лейаут не указан, будет использоваться `layouts/default.vue`.

</note>

<important>

Если в приложении один лейаут, разумнее оформить разметку в [`app.vue`](/docs/3.x/directory-structure/app) вместо отдельного каталога `layouts/`.

</important>

<important>

В отличие от других компонентов, ваши лейауты должны иметь один корневой элемент, чтобы позволить Nuxt применять переходы между изменениями лейаутов, и этот корневой элемент не может быть `<slot />`.

</important>

## Лейаут по умолчанию

Добавьте `~/layouts/default.vue`:

```vue [layouts/default.vue]
<template>
  <div>
    <p>Некоторый контент лейаута по умолчанию, общий для всех страниц</p>
    <slot />
  </div>
</template>
```

В файле лейаута содержимое страницы будет отображаться в компоненте `<slot />`.

## Именованный лейаут

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

Затем вы можете использовать лейаут `custom` на своей странице:

```vue [pages/about.vue]twoslash
<script setup lang="ts">
declare module 'nuxt/app' {
  interface NuxtLayouts {
    'custom': unknown
  }
}
// ---cut---
definePageMeta({
  layout: 'custom',
})
</script>
```

<read-more to="/docs/3.x/directory-structure/pages#page-metadata">

Узнайте больше о `definePageMeta`.

</read-more>

Вы можете напрямую переопределить лейаут по умолчанию для всех страниц, используя свойство `name` [`<NuxtLayout>`](/docs/3.x/api/components/nuxt-layout):

```vue [app.vue]
<script setup lang="ts">
// Вы можете сделать выбор на основе вызова API или статуса входа в систему.
const layout = 'custom'
</script>

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

Если у вас есть лейаут во вложенных директориях, имя лейаута будет основано на пути к нему и имени файла, при этом дублирующиеся сегменты будут удалены.

<table>
<thead>
  <tr>
    <th>
      Файл
    </th>
    
    <th>
      Имя лейаута
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        ~/layouts/desktop/default.vue
      </code>
    </td>
    
    <td>
      <code>
        desktop-default
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        ~/layouts/desktop-base/base.vue
      </code>
    </td>
    
    <td>
      <code>
        desktop-base
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        ~/layouts/desktop/index.vue
      </code>
    </td>
    
    <td>
      <code>
        desktop
      </code>
    </td>
  </tr>
</tbody>
</table>

Для ясности мы рекомендуем, чтобы имя файла лейаута совпадало с его именем:

<table>
<thead>
  <tr>
    <th>
      Файл
    </th>
    
    <th>
      Имя лейаута
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        ~/layouts/desktop/DesktopDefault.vue
      </code>
    </td>
    
    <td>
      <code>
        desktop-default
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        ~/layouts/desktop-base/DesktopBase.vue
      </code>
    </td>
    
    <td>
      <code>
        desktop-base
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        ~/layouts/desktop/Desktop.vue
      </code>
    </td>
    
    <td>
      <code>
        desktop
      </code>
    </td>
  </tr>
</tbody>
</table>

<link-example to="/docs/3.x/examples/features/layouts">



</link-example>

## Динамическое изменение лейаута

Вы также можете использовать хелпер [`setPageLayout`](/docs/3.x/api/utils/set-page-layout) для динамического изменения лейаута:

```vue [app/pages/index.vue]twoslash
<script setup lang="ts">
declare module 'nuxt/app' {
  interface NuxtLayouts {
    'custom': unknown
  }
}
// ---cut---
function enableCustomLayout () {
  setPageLayout('custom')
}
definePageMeta({
  layout: false,
})
</script>

<template>
  <div>
    <button @click="enableCustomLayout">
      Обновить лейаут
    </button>
  </div>
</template>
```

Лейауты для отдельных маршрутов можно задать через свойство `appLayout` в правилах маршрутов:

```ts [nuxt.config.ts]
export default defineNuxtConfig({
  routeRules: {
    // Лейаут для конкретного маршрута
    '/admin': { appLayout: 'admin' },
    // Лейаут для нескольких маршрутов
    '/dashboard/**': { appLayout: 'dashboard' },
    // Отключить лейаут для маршрута
    '/landing': { appLayout: false },
  },
})
```

<tip>

Это удобно, когда лейауты задаются централизованно в конфигурации, а не в каждом файле страницы, или когда нужно применить лейаут к маршрутам без отдельных компонентов страниц (например, catch-all, совпадающим со многими путями).

</tip>

<link-example to="/docs/3.x/examples/features/layouts">



</link-example>

## Переопределение лейаута на постраничной основе

Если вы используете страницы, вы можете получить полный контроль, установив `layout: false`, а затем используя компонент `<NuxtLayout>` на странице.

<code-group>

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

<template>
  <div>
    <NuxtLayout name="custom">
      <template #header>
        Некоторое содержимое шаблона заголовка.
      </template>

      Остальная часть страницы
    </NuxtLayout>
  </div>
</template>
```

```vue [layouts/custom.vue]
<template>
  <div>
    <header>
      <slot name="header">
        Содержимое заголовка по умолчанию
      </slot>
    </header>
    <main>
      <slot />
    </main>
  </div>
</template>
```

</code-group>

<important>

Если вы используете `<NuxtLayout>` на своих страницах, убедитесь, что он не является корневым элементом (или [отключите лейаут/переходы страниц](/docs/3.x/getting-started/transitions#disable-transitions)).

</important>
