🪝 Navigation Hooks
Citadel integrates with Vue Router's navigation lifecycle through three hooks. Each hook triggers the patrol system that processes all registered outposts.
📋 Hook Types
| Hook | When | Can Block | Use Case |
|---|---|---|---|
BEFORE_EACH | Before navigation starts | Yes | Auth, permissions, redirects |
BEFORE_RESOLVE | After async components resolved | Yes | Data validation, final checks |
AFTER_EACH | After navigation completed | No | Analytics, logging, side effects |
For best understanding, read Vue Router's
🔄 Where Hooks Fit
Each hook triggers patrol which processes all applicable outposts in priority order.
📊 What Happens Inside a Hook
What happens when a navigation hook is triggered:
INFO
Logging and debug breakpoints only trigger when there are outposts to process for the current hook. If no outposts are registered for a hook, it returns ALLOW silently.
⚙️ Specifying Hooks
By default, outposts use beforeEach. Override with the hooks option:
import { NavigationHooks } from 'vue-router-citadel';
citadel.deployOutpost({
name: 'analytics',
hooks: [NavigationHooks.AFTER_EACH],
handler: ({ verdicts, to }) => {
trackPageView(to.path);
return verdicts.ALLOW;
},
});An outpost can handle multiple hooks:
citadel.deployOutpost({
name: 'admin-only',
hooks: [NavigationHooks.BEFORE_RESOLVE, NavigationHooks.AFTER_EACH],
handler: ({ verdicts, hook }) => {
if (hook === 'beforeResolve') {
// Check admin role
}
if (hook === 'afterEach') {
// Log admin page view
}
return verdicts.ALLOW;
},
});🔧 Handler Context
Every outpost handler receives a context object with navigation details:
interface NavigationOutpostContext {
verdicts: {
ALLOW: 'allow';
BLOCK: 'block';
};
to: RouteLocationNormalized; // target route
from: RouteLocationNormalized; // current route
router: Router; // router instance
hook: 'beforeEach' | 'beforeResolve' | 'afterEach';
}Usage example:
handler: ({ verdicts, to, from, router, hook }) => {
// Access route params
const userId = to.params.id;
// Access route meta
const requiresAuth = to.meta.requiresAuth;
// Check current hook
if (hook === 'afterEach') {
// Analytics, logging (return value ignored)
}
return verdicts.ALLOW;
};TIP
When a handler throws an error, the citadel catches it and handles gracefully. See Error Handling for the full error flow, onError, onTimeout, and afterEach behavior.
Diagram Legend
| Color | Meaning |
|---|---|
| 🟢 | Success, ALLOW, continue |
| 🟡 | Warning, redirect, deduplicate |
| 🔴 | Error, BLOCK, cancel |
| 🔵 | Logging (when logger is enabled) |
| 🟣 | Named debug breakpoint (debug: true) |