docs/guide/advanced/navigation-failures.md
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:
next(false)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.
::: tip 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.
:::
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.
:::
NavigationFailureTypeNavigationFailureType 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.All navigation failures expose to and from properties to reflect the target and current location respectively 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.