Fix: abortNavigation() Only Usable in Middleware in Nuxt

Error message:
abortNavigation() is only usable inside a route middleware handler.
middleware 2025-01-25

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

ActionIn MiddlewareIn Component
Stop navigationabortNavigation()throw createError()
RedirectnavigateTo('/path')navigateTo('/path')
Show errorabortNavigation({ 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.ts suffix