---
title: "vue-router-citadel — middleware-driven Vue Router protection"
description: "Layered route guards for Vue Router 4/5. Outpost architecture, verdict API, full TypeScript types. Open-source, on npm."
url: https://symonov.com/projects/vue-router-citadel/
---

# vue-router-citadel

Middleware-driven navigation control for Vue Router. Layered, predictable, scalable route protection.

**2026** · by **Dmytro Symonov** · shipped · `vue-router` `typescript` `npm` `oss`

[docs](https://vue-router-citadel.symonov.com/) [github ↗](https://github.com/Kassaila/vue-router-citadel) [npm ↗](https://www.npmjs.com/package/vue-router-citadel)

## the problem

Vue Router’s `beforeEach` global guards are flexible but unstructured: every project ends up re-inventing role checks, redirect chains, and “is the user logged in” branching. That logic gets glued to components or composables, becomes hard to test in isolation, and falls apart once an app needs nested route protection (admin → org → resource).

## the approach

Citadel splits the problem into two primitives:

- **Outposts** — composable middleware functions, each one returning a verdict (`allow`, `deny`, `redirect`, `next`).
- **Verdict pipeline** — outposts run in order, short-circuiting on the first non-`next` verdict. The result is a predictable, traceable navigation decision.

Type-safe end-to-end: outpost factories carry their context types through the pipeline so the final guard signature reflects the protected route’s actual data needs.

## stack

- TypeScript 5 (strict)
- Vue Router 4 + 5 (peer dependency, dual-version support)
- Vitest for unit coverage
- Vite + tsup for the library build

## links — external resources

- docs: [https://vue-router-citadel.symonov.com/](https://vue-router-citadel.symonov.com/)
- github: [https://github.com/Kassaila/vue-router-citadel](https://github.com/Kassaila/vue-router-citadel)
- npm: [https://www.npmjs.com/package/vue-router-citadel](https://www.npmjs.com/package/vue-router-citadel)
