Маршрутизация, страницы, макеты и навигация
Как эта тема связана с архитектурой Nuxt
В предыдущей статье мы разобрали, что Nuxt — это универсальный фреймворк, где клиентский UI и серверный runtime (Nitro) живут в одном проекте, а основной принцип — конвенции важнее конфигурации.
Маршрутизация в Nuxt — один из самых ярких примеров этого принципа:
вы создаёте файлы в pages/, а Nuxt автоматически превращает их в маршруты
вы группируете страницы по папкам, а Nuxt автоматически строит вложенные URL
вы описываете параметры в имени файла, а Nuxt автоматически создаёт динамические маршрутыОфициальные материалы для справки:
Nuxt pages directory
Nuxt layouts directory
Nuxt middleware directory
Документация Vue RouterФайловая маршрутизация: как pages/ превращается в URL
Nuxt строит маршруты на основе структуры файлов в pages/.
Базовые правила:
pages/index.vue соответствует /
pages/about.vue соответствует /about
папки внутри pages/ становятся сегментами URL
index.vue внутри папки соответствует корню этого сегмента!Соответствие файлов в pages и итоговых маршрутов
Таблица соответствий
| Файл в pages/ | Маршрут |
|---|---|
| pages/index.vue | / |
| pages/about.vue | /about |
| pages/blog/index.vue | /blog |
| pages/blog/post.vue | /blog/post |
| pages/users/index.vue | /users |
Важно: Nuxt использует Vue Router под капотом, но вам обычно не нужно вручную описывать список маршрутов.
Динамические маршруты: параметры в URL
Динамический маршрут нужен, когда часть URL меняется, например id пользователя или slug статьи.
В Nuxt динамика задаётся квадратными скобками в имени файла:
pages/users/[id].vue создаёт маршрут /users/:id
pages/blog/[slug].vue создаёт маршрут /blog/:slugКак читать параметры на странице
Внутри страницы параметры доступны через useRoute().
Практические замечания:
route.params содержит параметры как строки (это важно для id, который вы могли ожидать числом)
параметры появляются только на маршрутах, где они объявлены (если вы на /users, то id не будет)Catch-all маршруты
Иногда нужно обработать произвольную глубину пути, например для CMS-подобных страниц: /docs/a, /docs/a/b, /docs/a/b/c.
Для этого используют catch-all:
pages/docs/[...slug].vue соответствует /docs/*Чтение параметра будет выглядеть так:
Здесь parts обычно является массивом сегментов (например, ['a','b','c']). Это удобно, когда вы строите запрос к API или CMS на основе массива.
Вложенные маршруты: когда URL и интерфейс имеют иерархию
Вложенная структура URL обычно отражает структуру интерфейса.
Примеры, где это встречается:
список и карточка сущности: /users и /users/123
раздел и подразделы: /settings/profile, /settings/securityВложенность через папки
Самый частый подход — просто разложить файлы по папкам:
pages/settings/index.vue → /settings
pages/settings/profile.vue → /settings/profile
pages/settings/security.vue → /settings/securityКогда нужен “родительский” контейнер для дочерних страниц
Иногда вы хотите, чтобы у раздела был общий интерфейс, а внутрь подставлялись дочерние страницы (например, общий сайдбар в разделе настроек).
В Nuxt это делается через механизм вложенных маршрутов, где родительская страница должна отрисовать место для дочерней.
Ключевые элементы, которые стоит запомнить:
NuxtPage — компонент, который отрисовывает текущую страницу (или дочерний маршрут внутри родителя)
файловая структура определяет, какие страницы являются дочернимиНа практике это означает: если вы строите раздел с “рамкой” и внутренними вкладками, вам почти всегда понадобится родительская страница-контейнер.
Route groups: группировка файлов без влияния на URL
Иногда хочется сгруппировать страницы в файловой системе (для читаемости), но не менять URL.
Для этого используются группы маршрутов с круглыми скобками в имени папки.
Идея:
папка (admin) группирует файлы
сегмент (admin) не попадает в URLПример логики:
pages/(admin)/users.vue может соответствовать /usersЭто полезно для больших проектов, где важно поддерживать порядок в pages/.
Макеты: layouts/ как каркас страниц
Макет (layout) — это общий каркас для набора страниц: шапка, подвал, боковая панель, общая сетка.
Чем layout отличается от компонента:
layout определяет структуру страницы на уровне маршрута
компонент — это переиспользуемый элемент внутри страницыLayout по умолчанию
Если вы создаёте layouts/default.vue, он будет применяться ко всем страницам, где явно не выбран другой layout.
Выбор layout для конкретной страницы
Обычно layout задают через метаданные страницы.
Здесь:
layout: 'auth' означает, что будет использован файл layouts/auth.vue
если такого файла нет, Nuxt не сможет применить layout (это ошибка уровня проекта)Когда полезно иметь несколько макетов
Типичные наборы layout в продакшен-приложении:
default для публичной части
auth для страниц входа и регистрации
dashboard для личного кабинета
empty для страниц, где нужен “чистый” экран (например, спец-лендинги)Навигация: переходы между страницами
В Nuxt есть два важных сценария навигации:
переходы по ссылкам внутри приложения без перезагрузки страницы
программная навигация из кода после события (например, после логина)Навигация ссылками
Для внутренних переходов используют NuxtLink.
Почему это важно:
переход происходит клиентски (быстрее, чем полная перезагрузка)
Nuxt может подгружать данные и чанки более эффективно
сохраняется SPA-ощущение, при этом SSR/SSG продолжают работатьЕсли вам нужно перейти на внешний сайт, используйте обычную ссылку, чтобы поведение было ожидаемым для пользователя.
Программная навигация
Есть два популярных инструмента:
navigateTo() — nuxt-ориентированный способ перехода
useRouter() — доступ к роутеру (подходит, когда нужны более низкоуровневые возможности)Пример с navigateTo():
Пример через роутер:
Что важно понимать про query:
query добавляет параметры строки запроса
пример выше приведёт к URL вида /users?tab=activeПолучение текущего маршрута
Чтобы прочитать путь, query или hash, используют useRoute():
Практическое правило:
useRoute() — “читать, где мы сейчас”
useRouter() или navigateTo() — “перейти куда-то”Навигационные middleware: контроль доступа и сценарии входа
Middleware — это код, который выполняется при переходах между страницами. Частый кейс — проверка авторизации.
В Nuxt middleware обычно размещают в middleware/.
Типы применения:
глобально для многих маршрутов
точечно для конкретной страницыПример: middleware “только для авторизованных”
Логику обычно строят вокруг того, есть ли у пользователя сессия или токен.
Здесь:
to — маршрут, на который вы пытаетесь перейти
from — маршрут, с которого вы уходите
navigateTo('/login') делает редиректВ реальном проекте isLoggedIn берётся из состояния (например, Pinia) или composable, который читает сессию.
Подключение middleware на странице
Часто middleware подключают через метаданные страницы:
Это означает: при входе на страницу будет выполнен middleware/auth.
Частые ошибки и как их избежать
Обращение к window или document без учёта SSR
Ожидание, что route.params.id будет числом
Попытка использовать внутреннюю навигацию обычной ссылкой, из-за чего теряются преимущества клиентских переходов
Смешивание ответственности: layout для каркаса, компоненты для UI-частей, composables для логикиЧто важно запомнить
pages/ определяет маршруты автоматически
квадратные скобки в имени файла создают динамические параметры
layouts/ задаёт каркас страниц, а layout выбирается через definePageMeta
для внутренней навигации используйте NuxtLink, для переходов из кода — navigateTo или router.push
middleware помогает контролировать доступ и выполнять редиректы при навигации