Navigation Failures
New in 3.4.0
When using router-link
, Vue Router calls router.push
to trigger a navigation. While the expected behavior for most links is to navigate a user to a new page, there are a few situations where users will remain on the same page:
- Users are already on the page that they are trying to navigate to
- A navigation guard aborts the navigation by calling
next(false)
- A navigation guard throws an error or calls
next(new Error())
When using a router-link
component, none of these failures will log an error. However, if you are using router.push
or router.replace
, you might come across an "Uncaught (in promise) Error" message followed by a more specific message in your console. Let's understand how to differentiate Navigation Failures.
Background story
In v3.2.0, Navigation Failures were exposed through the two optional callbacks of router.push
: onComplete
and onAbort
. Since version 3.1.0, router.push
and router.replace
return a Promise if no onComplete
/onAbort
callback is provided. This Promise resolves instead of invoking onComplete
and rejects instead of invoking onAbort
.
Detecting Navigation Failures
Navigation Failures are Error
instances with a few extra properties. To check if an error comes from the Router, use the isNavigationFailure
function:
import VueRouter from 'vue-router'
const { isNavigationFailure, NavigationFailureType } = VueRouter
// trying to access the admin page
router.push('/admin').catch(failure => {
if (isNavigationFailure(failure, NavigationFailureType.redirected)) {
// show a small notification to the user
showToast('Login in order to access the admin panel')
}
})
TIP
If you omit the second parameter: isNavigationFailure(failure)
, it will only check if the error is a Navigation Failure.
NavigationFailureType
NavigationFailureType
help developers to differentiate between the various types of Navigation Failures. There are four different types:
redirected
:next(newLocation)
was called inside of a navigation guard to redirect somewhere else.aborted
:next(false)
was called inside of a navigation guard to the navigation.cancelled
: A new navigation completely took place before the current navigation could finish. e.g.router.push
was called while waiting inside of a navigation guard.duplicated
: The navigation was prevented because we are already at the target location.
Navigation Failures's properties
All navigation failures expose to
and from
properties to reflect the current location as well as the target location for the navigation that failed:
// trying to access the admin page
router.push('/admin').catch(failure => {
if (isNavigationFailure(failure, NavigationFailureType.redirected)) {
failure.to.path // '/admin'
failure.from.path // '/'
}
})
In all cases, to
and from
are normalized route locations.