Auth Checks & Redirects Before a Route Renders
Route Middleware
Route middleware runs before a route activates — the right place for auth checks, feature flags, and conditional redirects.
What you'll learn
- Write a global middleware file
- Apply named middleware via definePageMeta
- Return navigateTo from middleware to redirect
Route middleware are functions that run before a route activates. Use them for authentication, authorization, feature flags, A/B redirects, and analytics ping-on-enter. They run on both server and client.
Global Middleware
A file ending in .global.ts runs on every navigation:
// middleware/auth.global.ts
export default defineNuxtRouteMiddleware((to) => {
const user = useUser()
// protect everything under /app
if (to.path.startsWith('/app') && !user.value) {
return navigateTo('/login')
}
}) Return navigateTo(...) to redirect, abortNavigation(...) to cancel, or nothing to continue.
Named Middleware
For middleware that should only apply to specific pages, drop the .global suffix:
// middleware/admin.ts
export default defineNuxtRouteMiddleware(() => {
const user = useUser()
if (user.value?.role !== 'admin') {
return abortNavigation('Admin access required')
}
}) Attach it from the page with definePageMeta:
<!-- pages/admin/index.vue -->
<script setup lang="ts">
definePageMeta({ middleware: 'admin' })
</script>
<template>
<h1>Admin dashboard</h1>
</template> You can pass an array to chain multiple middlewares — they run in order.
Inline Middleware
For a one-off check, define the function inline:
<script setup lang="ts">
definePageMeta({
middleware: [
(to, from) => {
if (to.query.legacy) return navigateTo('/new-page')
},
],
})
</script> When Middleware Runs
Middleware fires:
- On every server-rendered request that hits Nuxt.
- On every client-side navigation triggered by
NuxtLinkornavigateTo.
That symmetry is the point — auth checks happen on both sides, so neither SSR pages nor SPA navigation can leak protected content.
Route Validation →