Route Middleware
Nuxt 3 middleware provides route-level protection and access control throughout the application. The boilerplate includes three middleware types for different security levels.
Middleware Types
Authentication Middleware
Protects routes that require user login.
// middleware/auth.ts
export default defineNuxtRouteMiddleware((to) => {
const user = useSupabaseUser()
const protectedRoutes = ['/dashboard', '/settings', '/billing', '/profile']
const requiresAuth = protectedRoutes.some(route => to.path.startsWith(route))
if (requiresAuth && !user.value) {
const redirectTo = to.fullPath
return navigateTo(`/auth/login?redirect=${encodeURIComponent(redirectTo)}`)
}
})Usage in pages:
definePageMeta({
middleware: 'auth'
})Protected routes: Dashboard, settings, billing, profile pages
Admin Middleware
Restricts access to admin-only areas using email-based authorization.
// middleware/admin.ts
export default defineNuxtRouteMiddleware((to) => {
const user = useSupabaseUser()
if (!user.value) {
return navigateTo('/auth/login')
}
const adminEmails = [
'milan.herbe@gmail.com',
'mhdev@flink-agency.dev'
]
if (!adminEmails.includes(user.value.email || '')) {
throw createError({
statusCode: 403,
statusMessage: 'Access denied. Admin privileges required.'
})
}
})Usage in pages:
definePageMeta({
layout: 'admin',
middleware: 'admin'
})Protected routes: All /admin/* pages including user management, analytics, and subscription management
Subscription Middleware
Controls access based on subscription plans and feature availability.
// middleware/subscription.ts
export default defineNuxtRouteMiddleware(async (to) => {
const user = useSupabaseUser()
if (!user.value) return
const requiredPlan = to.meta.requiresPlan as string
const requiredFeature = to.meta.requiresFeature as string
if (requiredPlan || requiredFeature) {
const { useSubscription } = await import('@/composables/useSubscription')
const { checkAccess, getCurrentSubscription } = useSubscription()
const subscription = await getCurrentSubscription()
if (requiredPlan && subscription?.plan?.name !== requiredPlan) {
return navigateTo('/upgrade?plan=' + requiredPlan)
}
if (requiredFeature && !checkAccess(requiredFeature)) {
return navigateTo('/upgrade?feature=' + requiredFeature)
}
}
})Usage in pages:
definePageMeta({
middleware: 'subscription',
requiresPlan: 'pro',
requiresFeature: 'advanced-analytics'
})Implementation Details
Route Protection Flow
- User visits protected route - Middleware executes before page load
- Authentication check - Verifies user session exists
- Authorization check - Validates user permissions/subscription
- Access decision - Allows access or redirects to appropriate page
Redirect Behavior
- Unauthenticated users - Redirected to
/auth/loginwith return URL - Unauthorized users - Receive 403 error or redirect to upgrade page
- Subscription required - Redirected to
/upgradewith plan/feature context
Page Meta Configuration
Middleware is applied using definePageMeta() in page components:
// Basic authentication
definePageMeta({
middleware: 'auth'
})
// Admin access
definePageMeta({
layout: 'admin',
middleware: 'admin'
})
// Subscription-based access
definePageMeta({
middleware: 'subscription',
requiresPlan: 'enterprise',
requiresFeature: 'custom-branding'
})Security Considerations
- Email-based admin auth - Simple but should be replaced with role-based system in production
- Client-side checks - Middleware runs on client, server-side validation still required
- Subscription validation - Real-time checks against current subscription status
- Graceful redirects - Preserves intended destination for post-login navigation
The middleware system provides layered security from basic authentication to feature-level access control, ensuring users only access content they're authorized to view.