Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 25 additions & 2 deletions docs/advanced-concepts/hooks.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@ onAfterRouteEnter: (to, context) => {

### On Error

- **onError** Triggered whenever an unexpected error is thrown. Error hooks are run in the order they were registered.
- **onError** Triggered whenever an unexpected error is thrown. Error hooks are run in the order they were registered. The hook is provided both the error and the [error context](/advanced-concepts/hooks#error-context).

### On Rejection

- **onRejection** Triggered whenever a rejection is triggered. Rejection hooks are run in the order they were registered. The hook is provided both the rejection and the [rejection context](/advanced-concepts/hooks#rejection-context).

## Context

Expand All @@ -43,20 +47,31 @@ If the hooks lifecycle is a [before](/advanced-concepts/hooks#before-hooks) hook
| ---- | ---- |
| abort | Stops the router from continuing with route change |

### Error Context

If the hook is `onError`, you'll also have access to the following properties in your context:

| Property | Description |
| ---- | ---- |
| to | What was the destination route prior to the error being thrown |
| source | String value indicating where the error occurred. Possible values are `'props'`, `'hook'`, and `'component'` |

### Rejection Context

If the hook is `onRejection`, you'll also have access to the following properties in your context:

| Property | Description |
| ---- | ---- |
| to | What was the destination route prior to the rejection being triggered |
| from | What was the route prior to the rejection being triggered |

## Levels

Hooks can be registered **globally**, on your **route**, or from within a **component**. This is useful for both providing the most convenient devx, but also can be a useful tool for ensuring proper execution order of your business logic.

### Execution Order

1. Global before hooks
1. Global before hooks
2. Route before hooks
3. Component before hooks
4. Component after hooks
Expand All @@ -79,6 +94,14 @@ route.onAfterRouteEnter((to, context) => {
})
```

### Rejection

```ts
rejection.onRejection((rejection, context) => {
...
})
```

### Component

In order to register a hook from within a component, you must use the [composition API](https://vuejs.org/guide/extras/composition-api-faq.html#composition-api-faq).
Expand Down
23 changes: 23 additions & 0 deletions docs/advanced-concepts/rejections.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,26 @@ const rejection = useRejection()

const rejectionType = computed(() => rejection.value.type)
```

## Title

The `setTitle` callback is used to set the document title for the rejection. The callback is given the resolved route and a context object. The callback can be async, and should return a string that should be set as the document.title.

The context object has the following properties:

| Property | Type | Description |
| -------- | ---- | ----------- |
| from | ResolvedRoute | The route that is being navigated from. |
| getParentTitle | () => Promise<string \| undefined> | Promise that resolves to the title of the parent route. |

```ts
import { createRejection } from '@kitbag/router'

const authNeededRejection = createRejection({
type: 'AuthNeeded',
})

authNeededRejection.setTitle((to, context) => {
return `Unauthorized!`
})
```
60 changes: 60 additions & 0 deletions docs/core-concepts/routes.md
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,37 @@ home.onBeforeRouteEnter(() => {
})
```

## Title

The `setTitle` callback is used to set the document title for the route. The callback is given the resolved route and a context object. The callback can be async, and should return a string that should be set as the document.title.

The context object has the following properties:

| Property | Description |
| -------- | ----------- |
| from | What was the route prior to the hook's execution |
| getParentTitle | A function that returns the title of the parent route. |

```ts
import { createRoute } from '@kitbag/router'

const user = createRoute({
name: 'user.profile',
path: '/user/:userId',
})

user.setTitle((to, context) => {
const user = userStore.getUser(to.params.userId)
return `Profile: ${user.name}`
})
```

:::info

There is also a `setTitle` callback on [rejections](/advanced-concepts/rejections#title).

:::

## Context

The context for a route is the collection of routes and rejections that are associated with the route. The context you provide to this route will be available to the hooks and props callback functions for this route.
Expand Down Expand Up @@ -236,3 +267,32 @@ const home = createRoute({
},
})
```

## Hoisting

When the `hoist` property is true, the route will be treated as a root route. This allows you to leverage the component nesting without having to use a nested URL.

```ts
const parentRoute = createRoute({
name: 'parent',
path: '/parent',
})

const regularChildRoute = createRoute({
parent: parentRoute,
name: 'parent.regular',
path: '/regular',
})

const hoistedExample = createRoute({
parent: parentRoute,
name: 'parent.nested',
path: '/nested',
hoist: true,
})

regularChildRoute.stringify()
// ^ "/parent/regular"
hoistedExample.string()
// ^ "/nested"
```
6 changes: 3 additions & 3 deletions src/types/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ export type RejectionHookContext<
TRouteFrom extends Route = TRoutes[number]
> = {
to: ResolvedRouteUnion<TRouteTo> | null,
from: ResolvedRouteUnion<TRouteFrom> | null
from: ResolvedRouteUnion<TRouteFrom> | null,
}

export type RejectionHook<
Expand All @@ -307,7 +307,7 @@ export type AddRejectionHook<
> = (hook: RejectionHook<TRejections, TRoutes, TRouteTo, TRouteFrom>) => HookRemove

export type RejectionHookRunner<TRejection extends Rejection = Rejection, TRoutes extends Routes = Routes> = (
rejection: TRejection,
rejection: TRejection,
context: { to: RouterResolvedRouteUnion<TRoutes> | null, from: RouterResolvedRouteUnion<TRoutes> | null }
) => void

Expand Down Expand Up @@ -344,6 +344,6 @@ export type ErrorHookRunnerContext<TRoutes extends Routes = Routes> = {
}

export type ErrorHookRunner = (
error: unknown,
error: unknown,
context: ErrorHookRunnerContext
) => void
Loading