Skip to content

Commit 347eb23

Browse files
committed
docs: add navigation failures
1 parent 94606a7 commit 347eb23

File tree

2 files changed

+127
-57
lines changed

2 files changed

+127
-57
lines changed

Diff for: docs/.vuepress/config.js

+74-57
Original file line numberDiff line numberDiff line change
@@ -26,23 +26,39 @@ module.exports = {
2626
description: 'Vue.js 공식 라우터'
2727
},
2828
'/fr/': {
29-
lang: 'fr',
30-
title: 'Vue Router',
31-
description: 'Routeur officiel pour Vue.Js'
29+
lang: 'fr',
30+
title: 'Vue Router',
31+
description: 'Routeur officiel pour Vue.Js'
3232
}
3333
},
3434
head: [
3535
['link', { rel: 'icon', href: `/logo.png` }],
36-
['link', { rel: 'apple-touch-icon', href: `/icons/apple-touch-icon-152x152.png` }],
37-
['link', { rel: 'mask-icon', href: '/icons/safari-pinned-tab.svg', color: '#3eaf7c' }],
38-
['meta', { name: 'msapplication-TileImage', content: '/icons/msapplication-icon-144x144.png' }],
36+
[
37+
'link',
38+
{ rel: 'apple-touch-icon', href: `/icons/apple-touch-icon-152x152.png` }
39+
],
40+
[
41+
'link',
42+
{
43+
rel: 'mask-icon',
44+
href: '/icons/safari-pinned-tab.svg',
45+
color: '#3eaf7c'
46+
}
47+
],
48+
[
49+
'meta',
50+
{
51+
name: 'msapplication-TileImage',
52+
content: '/icons/msapplication-icon-144x144.png'
53+
}
54+
]
3955
],
4056
serviceWorker: true,
4157
theme: 'vue',
4258
themeConfig: {
4359
algolia: {
4460
apiKey: 'f854bb46d3de7eeb921a3b9173bd0d4c',
45-
indexName: 'vue-router',
61+
indexName: 'vue-router'
4662
},
4763
repo: 'vuejs/vue-router',
4864
docsDir: 'docs',
@@ -92,7 +108,8 @@ module.exports = {
92108
'/guide/advanced/transitions.md',
93109
'/guide/advanced/data-fetching.md',
94110
'/guide/advanced/scroll-behavior.md',
95-
'/guide/advanced/lazy-loading.md'
111+
'/guide/advanced/lazy-loading.md',
112+
'/guide/advanced/navigation-failures.md'
96113
]
97114
}
98115
]
@@ -298,55 +315,55 @@ module.exports = {
298315
]
299316
},
300317
'/fr/': {
301-
label: 'Français',
302-
selectText: 'Langues',
303-
editLinkText: 'Editer cette page sur Github',
304-
nav: [
305-
{
306-
text: 'Guide',
307-
link: '/fr/guide/'
308-
},
309-
{
310-
text: 'API',
311-
link: '/fr/api/'
312-
},
313-
{
314-
text: 'Notes de version',
315-
link: 'https://github.com/vuejs/vue-router/releases'
316-
}
317-
],
318-
sidebar: [
319-
'/fr/installation.md',
320-
'/fr/',
321-
{
322-
title: 'Essentiels',
323-
collapsable: false,
324-
children: [
325-
'/fr/guide/',
326-
'/fr/guide/essentials/dynamic-matching.md',
327-
'/fr/guide/essentials/nested-routes.md',
328-
'/fr/guide/essentials/navigation.md',
329-
'/fr/guide/essentials/named-routes.md',
330-
'/fr/guide/essentials/named-views.md',
331-
'/fr/guide/essentials/redirect-and-alias.md',
332-
'/fr/guide/essentials/passing-props.md',
333-
'/fr/guide/essentials/history-mode.md'
334-
]
335-
},
336-
{
337-
title: 'Avancés',
338-
collapsable: false,
339-
children: [
340-
'/fr/guide/advanced/navigation-guards.md',
341-
'/fr/guide/advanced/meta.md',
342-
'/fr/guide/advanced/transitions.md',
343-
'/fr/guide/advanced/data-fetching.md',
344-
'/fr/guide/advanced/scroll-behavior.md',
345-
'/fr/guide/advanced/lazy-loading.md'
346-
]
347-
}
348-
]
349-
},
318+
label: 'Français',
319+
selectText: 'Langues',
320+
editLinkText: 'Editer cette page sur Github',
321+
nav: [
322+
{
323+
text: 'Guide',
324+
link: '/fr/guide/'
325+
},
326+
{
327+
text: 'API',
328+
link: '/fr/api/'
329+
},
330+
{
331+
text: 'Notes de version',
332+
link: 'https://github.com/vuejs/vue-router/releases'
333+
}
334+
],
335+
sidebar: [
336+
'/fr/installation.md',
337+
'/fr/',
338+
{
339+
title: 'Essentiels',
340+
collapsable: false,
341+
children: [
342+
'/fr/guide/',
343+
'/fr/guide/essentials/dynamic-matching.md',
344+
'/fr/guide/essentials/nested-routes.md',
345+
'/fr/guide/essentials/navigation.md',
346+
'/fr/guide/essentials/named-routes.md',
347+
'/fr/guide/essentials/named-views.md',
348+
'/fr/guide/essentials/redirect-and-alias.md',
349+
'/fr/guide/essentials/passing-props.md',
350+
'/fr/guide/essentials/history-mode.md'
351+
]
352+
},
353+
{
354+
title: 'Avancés',
355+
collapsable: false,
356+
children: [
357+
'/fr/guide/advanced/navigation-guards.md',
358+
'/fr/guide/advanced/meta.md',
359+
'/fr/guide/advanced/transitions.md',
360+
'/fr/guide/advanced/data-fetching.md',
361+
'/fr/guide/advanced/scroll-behavior.md',
362+
'/fr/guide/advanced/lazy-loading.md'
363+
]
364+
}
365+
]
366+
}
350367
}
351368
}
352369
}

Diff for: docs/guide/advanced/navigation-failures.md

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Navigation Failures
2+
3+
When using `router-link`, Vue Router internally calls `router.push` to trigger a navigation. Depending on the current location and existing [Navigation Guards](./navigation-guards.md), this navigation might end up in a new page being shown, but there are a couple of situations where we will stay on the same page:
4+
5+
- We are already on the page we are trying to go to
6+
- A navigation guard aborts the navigation by calling `next(false)`
7+
- An error is thrown in a navigation by calling `next(new Error())`
8+
9+
When using a regular `router-link`, **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. This is part of the _Navigation Failures_ system in Vue Router and it is only available from version 3.2.0 onwards but existed for a long time before: through the two optional callbacks, `onComplete` and `onAbort` that can be passed to `router.push`. 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 `osComplete` and rejects instead of invoking `onAbort`.
10+
11+
## Detecting Navigation Failures
12+
13+
_Navigation Failures_ are `Error` instances with a few extra properties. Among them, you can find a `type` property. This will allow you to check the type of the navigation failure:
14+
15+
```js
16+
import { NavigationFailureTypes } from 'vue-router'
17+
18+
// trying to access an admin-only route
19+
router.push('/admin').catch(failure => {
20+
if (failure) {
21+
if (failure.type === NavigationFailureTypes.redirected) {
22+
// show a small notification to the user
23+
showToast('Login in order to access the admin panel')
24+
}
25+
}
26+
})
27+
```
28+
29+
## `NavigationFailureTypes`
30+
31+
`NavigationFailureTypes` exposes the following properties to differentiate _Navigation Failures_:
32+
33+
- `redirected`: `next(newLocation)` was called inside of a navigation guard to redirect somewhere else.
34+
- `aborted`: `next(false)` was called inside of a navigation guard to the navigation.
35+
- `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.
36+
- `duplicated`: The navigation was prevented because we are already at the target location.
37+
38+
## _Navigation Failures_'s properties
39+
40+
Apart from exposing a `type` property, all navigation failures expose `to` and `from` properties to reflect the current location as well as the target location for the navigation that failed:
41+
42+
```js
43+
// given we are at `/`
44+
router.push('/admin').catch(failure => {
45+
if (failure) {
46+
if (failure.type === NavigationFailureTypes.redirected) {
47+
failure.to.path // '/admin'
48+
failure.from.path // '/'
49+
}
50+
}
51+
```
52+
53+
In all cases, `from` and `to` are normalized route locations.

0 commit comments

Comments
 (0)