What Causes This Error?
This error occurs when you call abortNavigation() outside of a route middleware. The function is designed specifically for middleware and won’t work in components, pages, or other contexts.
The Problem
<!-- pages/protected.vue -->
<script setup>
// ❌ Wrong - abortNavigation called in a page component
const user = useUser()
if (!user.value) {
abortNavigation() // Error!
}
</script>
The Fix
Use abortNavigation() only inside middleware:
// middleware/auth.ts
export default defineNuxtRouteMiddleware((to, from) => {
const user = useUser()
if (!user.value) {
// ✅ Correct - inside middleware
return abortNavigation()
}
})
What abortNavigation Does
abortNavigation() stops the current navigation and optionally shows an error:
// middleware/auth.ts
export default defineNuxtRouteMiddleware((to) => {
// Stop navigation silently
return abortNavigation()
// Or stop with an error
return abortNavigation({
statusCode: 403,
message: 'Access denied'
})
})
Alternatives for Components
Alternative 1: Use navigateTo Instead
<script setup>
const user = useUser()
// ✅ Redirect instead of aborting
if (!user.value) {
navigateTo('/login')
}
</script>
Alternative 2: Use Middleware
<!-- pages/protected.vue -->
<script setup>
definePageMeta({
middleware: 'auth' // Let middleware handle it
})
</script>
// middleware/auth.ts
export default defineNuxtRouteMiddleware((to, from) => {
const user = useUser()
if (!user.value) {
// Redirect to login
return navigateTo('/login')
// Or abort with error page
return abortNavigation({
statusCode: 401,
message: 'Please log in'
})
}
})
Alternative 3: Throw an Error
<script setup>
const user = useUser()
if (!user.value) {
throw createError({
statusCode: 403,
message: 'Access denied'
})
}
</script>
Middleware Examples
Authentication Guard
// middleware/auth.ts
export default defineNuxtRouteMiddleware((to) => {
const { loggedIn } = useAuth()
if (!loggedIn.value) {
if (to.path !== '/login') {
return navigateTo('/login')
}
}
})
Role-Based Access
// middleware/admin.ts
export default defineNuxtRouteMiddleware((to) => {
const user = useUser()
if (!user.value?.isAdmin) {
return abortNavigation({
statusCode: 403,
statusMessage: 'Admin access required'
})
}
})
Feature Flag Guard
// middleware/feature-flag.ts
export default defineNuxtRouteMiddleware((to) => {
const config = useRuntimeConfig()
if (!config.public.newFeatureEnabled) {
return abortNavigation({
statusCode: 404,
message: 'Feature not available'
})
}
})
Maintenance Mode
// middleware/maintenance.global.ts
export default defineNuxtRouteMiddleware((to) => {
const config = useRuntimeConfig()
if (config.public.maintenanceMode && to.path !== '/maintenance') {
return navigateTo('/maintenance')
}
})
Using abortNavigation Options
export default defineNuxtRouteMiddleware((to) => {
// Simple abort (404-like behavior)
return abortNavigation()
// Abort with custom error
return abortNavigation({
statusCode: 403,
statusMessage: 'Forbidden',
message: 'You do not have permission to access this page'
})
// Abort with fatal error (shows error page)
return abortNavigation({
statusCode: 500,
fatal: true,
message: 'Something went wrong'
})
})
Conditional Navigation in Middleware
export default defineNuxtRouteMiddleware((to, from) => {
const auth = useAuth()
// Allow navigation
if (auth.isAuthenticated) {
return // Continue to the route
}
// Redirect
if (to.path.startsWith('/app')) {
return navigateTo('/login')
}
// Abort with error
if (to.path.startsWith('/admin')) {
return abortNavigation({
statusCode: 403,
message: 'Admin access required'
})
}
})
Quick Reference
| Action | In Middleware | In Component |
|---|---|---|
| Stop navigation | abortNavigation() | throw createError() |
| Redirect | navigateTo('/path') | navigateTo('/path') |
| Show error | abortNavigation({ statusCode: 403 }) | throw createError({ statusCode: 403 }) |
Quick Checklist
-
abortNavigation()is only in middleware files - For components, use
navigateTo()for redirects - For components, use
throw createError()for errors - Middleware is applied via
definePageMeta - Global middleware uses
.global.tssuffix