Макеты (layouts) и навигация

Layout — это рамка вокруг страниц: шапка, подвал, меню пишутся один раз, а NuxtLink переключает страницы без перезагрузки.
Суть: макет (layout) оборачивает страницы общей разметкой. Файл layouts/default.vue применяется автоматически, слот <slot/> — место для контента страницы. Навигация внутри приложения идёт через <NuxtLink>, который меняет маршрут без полной перезагрузки.

Почти у каждого сайта есть постоянные элементы: шапка с логотипом, навигационное меню, подвал. Копировать их в каждую страницу — путь к боли. Nuxt решает это макетами. Layout — это компонент-рамка, внутри которой через слот подставляется содержимое конкретной страницы.

Файл layouts/default.vue применяется ко всем страницам автоматически. Минимальный макет выглядит так:

<template>
  <div>
    <header>Логотип и меню</header>
    <main>
      <slot />   <!-- сюда подставится страница -->
    </main>
    <footer>© 2025</footer>
  </div>
</template>

Можно иметь несколько макетов: layouts/admin.vue для админки, layouts/empty.vue без шапки и т.д. Страница выбирает макет через definePageMeta:

<script setup>
definePageMeta({ layout: "admin" })
</script>

Чтобы между страницами можно было переходить, используют <NuxtLink>. В отличие от обычного <a href>, он не перезагружает страницу целиком: Nuxt перехватывает клик, меняет маршрут на клиенте и подставляет новый компонент. Это и быстро, и сохраняет состояние приложения.

<template>
  <nav>
    <NuxtLink to="/">Главная</NuxtLink>
    <NuxtLink to="/blog">Блог</NuxtLink>
  </nav>
</template>

Динамические маршруты — это ещё и про производительность контентных сайтов. Один шаблон [slug].vue в связке с prerender умеет на этапе сборки сгенерировать тысячи статических страниц блога или каталога: Nuxt пройдёт по списку идентификаторов и отрендерит каждую в готовый HTML. Так вы получаете и удобство одного шаблона, и скорость статики, и идеальную индексацию. Это типичный паттерн для документации, новостных лент и магазинов, где сущностей много, а разметка у них общая.

Как работает под капотом

Nuxt оборачивает <NuxtPage /> в компонент <NuxtLayout />, который по имени из definePageMeta выбирает нужный файл из layouts/ и рендерит страницу в его слот. При навигации через NuxtLink срабатывает клиентский роутер Vue Router: вместо запроса к серверу он подменяет компонент в <NuxtPage />. Браузерный URL обновляется через History API, поэтому кнопка «назад» работает штатно.

Смоделируем выбор макета по имени — простая диспетчеризация:

// Как Nuxt выбирает layout для страницы.
const layouts = {
  default: (content) => "[шапка]\n" + content + "\n[подвал]",
  admin:   (content) => "[админ-меню]\n" + content,
  empty:   (content) => content,   // без обёртки
};

function renderWithLayout(pageMeta, pageContent) {
  const name = pageMeta.layout || "default";
  const wrap = layouts[name] || layouts.default;
  return wrap(pageContent);
}

console.log(renderWithLayout({}, "Главная страница"));
console.log("---");
console.log(renderWithLayout({ layout: "admin" }, "Панель управления"));
console.log("---");
console.log(renderWithLayout({ layout: "empty" }, "Страница входа"));

Попробуй сам ▶ — каждая страница «вкладывается» в свою рамку. Так же и Nuxt подставляет контент в слот выбранного макета.

Частые ошибки

  • Забыть <slot /> в макете. Без него содержимое страницы просто не отобразится.
  • Использовать <a href> для внутренних ссылок. Это вызывает полную перезагрузку и теряет преимущества SPA-навигации. Для внутренних переходов — NuxtLink.
  • Дублировать шапку в каждой странице. Общие элементы — задача макета, а не страницы.

Best practices

  • Один default.vue для основного каркаса, отдельные макеты — для админки, лендинга, страниц без хрома.
  • Внутренние ссылки — всегда NuxtLink; внешние — обычный <a>.
  • Логика, общая для всех страниц макета (например, загрузка профиля), хорошо ложится в сам layout.

Итог: макеты убирают дублирование разметки, а NuxtLink даёт мгновенную навигацию без перезагрузки. Дальше — защита и подготовка маршрутов через middleware.

Навигация в Nuxt — это не только переход между страницами, но и сохранение ощущения цельного приложения. Поскольку NuxtLink не перезагружает страницу, состояние в useState, открытые модальные окна и позиция прокрутки могут переживать переход, если это нужно. Nuxt также умеет управлять анимациями переходов между страницами и фокусом для доступности. Всё это вместе создаёт плавный опыт, ближе к нативному приложению, чем к классическому сайту с полными перезагрузками — и при этом первая загрузка остаётся быстрой благодаря SSR.

Проверьте себя
1. Что делает <slot /> в файле layout?
AЗагружает данные с сервера
BОбозначает место, куда подставляется содержимое конкретной страницы
CСоздаёт новую ссылку
DОтключает серверный рендеринг
2. Чем NuxtLink лучше обычного <a href> для внутренних переходов?
AОн работает только на сервере
BОн меняет маршрут на клиенте без полной перезагрузки страницы, сохраняя состояние приложения
CОн автоматически шифрует ссылки
DРазницы нет