Middleware: проверки перед переходом
Middleware — это охранник на входе в маршрут: он запускается до отрисовки страницы и может пропустить, перенаправить или отменить переход.
Суть: route middleware — функция, выполняемая перед переходом на маршрут. Она получает целевой и исходный маршруты и решает: пропустить, перенаправить через navigateTo или отменить через abortNavigation. Используется для авторизации и проверок доступа.
Часто перед показом страницы нужно что-то проверить: вошёл ли пользователь, есть ли у него права, существует ли запрашиваемая сущность. Размазывать эти проверки по компонентам неудобно. Nuxt предлагает middleware — функции-перехватчики, которые выполняются до рендеринга маршрута.
Middleware живут в папке middleware/ и объявляются через defineNuxtRouteMiddleware. Функция получает два аргумента: to (куда идём) и from (откуда). Вернув navigateTo("/login"), вы перенаправите пользователя; вернув abortNavigation() — отмените переход; ничего не вернув — пропустите.
// middleware/auth.ts
export default defineNuxtRouteMiddleware((to, from) => {
const user = useUserState() // ваше состояние
if (!user.value) {
return navigateTo("/login") // не вошёл -> на вход
}
// вошёл -> ничего не возвращаем, пускаем дальше
})
Подключить такое middleware к странице можно через definePageMeta:
<script setup>
definePageMeta({ middleware: "auth" })
</script>
Есть и глобальные middleware: файл с суффиксом .global.ts (например middleware/log.global.ts) выполняется перед каждым переходом без явного указания.
Поток перехода на маршрут
клик по NuxtLink
|
v
[middleware] --(navigateTo)--> редирект на другой роут
| --(abortNavigation)--> переход отменён
| (ничего не вернул)
v
рендер целевой страницы
Полезно различать два уровня обёрток. app.vue — это самый внешний контейнер на всё приложение целиком: он есть всегда и оборачивает любой макет. Сами макеты в layouts/ — это сменные рамки уровнем ниже: публичная часть, админка, лендинг без шапки. Такое двухуровневое деление позволяет держать глобальное (например, тост-уведомления или модальные окна) в app.vue, а вариативное оформление страниц — в макетах. Когда структура усложняется, это разделение спасает от дублирования и путаницы.
Полезно помнить, что middleware бывает трёх видов по месту срабатывания. Анонимное (инлайн) задаётся прямо в definePageMeta функцией — удобно для разовой проверки одной страницы. Именованное лежит файлом в middleware/ и подключается по имени к нужным страницам — это переиспользуемый гейт вроде auth. Глобальное с суффиксом .global срабатывает на каждый переход без явного указания — для сквозной логики. Выбор между ними — это баланс между точечностью и охватом: не делайте глобальным то, что нужно лишь паре страниц.
Как работает под капотом
Middleware встраивается в navigation guard клиентского и серверного роутера. При SSR оно отрабатывает на сервере перед рендером, при клиентской навигации — в браузере перед сменой компонента. Поэтому проверки доступа надёжны в обоих режимах. Возврат navigateTo прерывает текущий переход и начинает новый; abortNavigation просто останавливает его.
Смоделируем цепочку middleware — каждый шаг может пропустить или прервать переход:
// Конвейер проверок перед переходом на маршрут.
function runMiddleware(chain, to, user) {
for (const mw of chain) {
const result = mw(to, user);
if (result) {
return { blocked: true, reason: result }; // редирект/отмена
}
}
return { blocked: false }; // все пропустили
}
const auth = (to, user) => user ? null : "redirect:/login";
const admin = (to, user) => (user && user.role === "admin") ? null : "abort:403";
console.log("Гость на /profile:",
runMiddleware([auth], "/profile", null));
console.log("Юзер на /admin:",
runMiddleware([auth, admin], "/admin", { role: "user" }));
console.log("Админ на /admin:",
runMiddleware([auth, admin], "/admin", { role: "admin" }));
Попробуй сам ▶ — конвейер останавливается на первой неуспешной проверке, как и реальные middleware Nuxt.
Частые ошибки
- Не возвращать результат. Чтобы перенаправить, нужно именно
return navigateTo(...), а не просто вызвать функцию. - Полагаться только на клиентскую проверку. Middleware — это UX-гейт, но настоящую авторизацию данных делайте ещё и на сервере в API.
- Тяжёлые операции в middleware. Оно тормозит каждый переход — держите его лёгким.
Best practices
- Именованные middleware — для конкретных защищённых страниц, глобальные — для сквозной логики (логирование, локаль).
- Всегда дублируйте критичные проверки доступа на сервере: клиент можно обмануть.
- Возвращайте
navigateToдля редиректа иabortNavigationдля жёсткой отмены.
Итог: middleware — это охрана на входе в маршрут. Она решает судьбу перехода до рендера, что идеально для авторизации. На этом раздел о маршрутизации завершён — переходим к компонентам и composables.