{"id":12563,"library":"vue-router-multiguard","title":"Vue Router Multiguard","description":"This package provides a utility to combine multiple Vue Router navigation guards into a single `beforeEnter` or `beforeEach` hook. It allows developers to specify an array of functions that will be executed serially, stopping when any guard calls `next()` with an argument (e.g., a path to redirect to) or when all guards complete without redirection. The current stable version is 1.0.3, which includes official TypeScript support, making it well-integrated into modern Vue 2/3 applications using TypeScript. As a lightweight utility, its release cadence is generally driven by bug fixes or minor enhancements. Its primary differentiator is simplifying the composition of multiple guards without complex nesting or manual chaining, providing a clean API for common use cases like layered authentication and authorization.","status":"active","version":"1.0.3","language":"javascript","source_language":"en","source_url":"https://github.com/atanas-angelov-dev/vue-router-multiguard","tags":["javascript","vue-router","vue-router-guard","guard","multiple-guard","typescript"],"install":[{"cmd":"npm install vue-router-multiguard","lang":"bash","label":"npm"},{"cmd":"yarn add vue-router-multiguard","lang":"bash","label":"yarn"},{"cmd":"pnpm add vue-router-multiguard","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"The `multiguard` function is a default export. Using named import syntax will result in an undefined value.","wrong":"import { multiguard } from 'vue-router-multiguard';","symbol":"multiguard","correct":"import multiguard from 'vue-router-multiguard';"},{"note":"While primarily designed for ES modules, if using CommonJS `require`, access the default export via `.default` due to ESM interop nuances in some environments.","wrong":"const multiguard = require('vue-router-multiguard');","symbol":"multiguard (CommonJS)","correct":"const multiguard = require('vue-router-multiguard').default;"},{"note":"TypeScript types are included since v1.0.3. The main `multiguard` function is a default export, but you can import the `Multiguard` type directly from the package for explicit type hinting.","wrong":"import { Multiguard } from 'vue-router-multiguard/dist/types';","symbol":"Type definitions","correct":"import multiguard, { Multiguard } from 'vue-router-multiguard';"}],"quickstart":{"code":"import Vue from 'vue';\nimport VueRouter, { RouteConfig } from 'vue-router';\nimport multiguard from 'vue-router-multiguard';\n\nVue.use(VueRouter);\n\n// Example guard functions\nconst requireAuth = (to, from, next) => {\n    const isAuthenticated = localStorage.getItem('userToken'); // Simulate auth check\n    if (to.meta?.requiresAuth && !isAuthenticated) {\n        console.log(`Guard 'requireAuth' blocked for ${to.path}: User not authenticated.`);\n        next('/login'); // Redirect to login page\n    } else {\n        next(); // Proceed\n    }\n};\n\nconst requireAdmin = (to, from, next) => {\n    const userRole = localStorage.getItem('userRole'); // Simulate role check\n    if (to.meta?.requiresAdmin && userRole !== 'admin') {\n        console.log(`Guard 'requireAdmin' blocked for ${to.path}: Not an administrator.`);\n        next('/access-denied'); // Redirect for insufficient permissions\n    } else {\n        next(); // Proceed\n    }\n};\n\nconst logRoute = (to, from, next) => {\n    console.log(`Guard 'logRoute' entered: ${from.path} -> ${to.path}`);\n    next(); // Always proceed\n};\n\nconst routes: Array<RouteConfig> = [\n    {\n        path: '/',\n        component: { template: '<div><h1>Home</h1><p>Public access.</p></div>' },\n        name: 'home'\n    },\n    {\n        path: '/dashboard',\n        component: { template: '<div><h1>Dashboard</h1><p>Authenticated access.</p></div>' },\n        name: 'dashboard',\n        meta: { requiresAuth: true },\n        beforeEnter: multiguard([logRoute, requireAuth]) // Combined guards\n    },\n    {\n        path: '/admin',\n        component: { template: '<div><h1>Admin Panel</h1><p>Admin-only access.</p></div>' },\n        name: 'admin',\n        meta: { requiresAuth: true, requiresAdmin: true },\n        beforeEnter: multiguard([logRoute, requireAuth, requireAdmin]) // Multiple combined guards\n    },\n    {\n        path: '/login',\n        component: { template: '<div><h1>Login</h1><p>Please log in.</p></div>' },\n        name: 'login'\n    },\n    {\n        path: '/access-denied',\n        component: { template: '<div><h1>Access Denied</h1><p>You do not have permission to view this page.</p></div>' },\n        name: 'access-denied'\n    }\n];\n\nconst router = new VueRouter({ routes });\n\n// Simulate user state for demonstration\nlocalStorage.setItem('userToken', 'fake-jwt-token-123'); // User is 'logged in'\nlocalStorage.setItem('userRole', 'user'); // User is not 'admin'\n\nconsole.log('--- Navigating to /dashboard (authenticated user) ---');\nrouter.push('/dashboard').catch(err => console.error('Navigation error:', err.message));\n\nsetTimeout(() => {\n    console.log('\\n--- Navigating to /admin (authenticated but not admin) ---');\n    router.push('/admin').catch(err => console.error('Navigation error:', err.message));\n}, 100);\n\nsetTimeout(() => {\n    console.log('\\n--- Navigating to /dashboard (unauthenticated user) ---');\n    localStorage.removeItem('userToken'); // Simulate logout\n    router.push('/dashboard').catch(err => console.error('Navigation error:', err.message));\n}, 200);\n\n// For a real app, you'd mount this to a Vue instance:\n// new Vue({ router, el: '#app' });","lang":"typescript","description":"This quickstart demonstrates how to apply multiple navigation guards to Vue Router routes using `multiguard`. It defines example guards for authentication, role-based access, and logging, then shows how to chain them effectively on `beforeEnter` hooks. The example includes simulated navigation attempts to illustrate how guards execute serially and can redirect early based on conditions, providing clear console output for each step."},"warnings":[{"fix":"Carefully order your guards in the `multiguard` array. Place fundamental checks like authentication before more specific checks like detailed permissions or logging.","message":"Guards passed to `multiguard` are executed strictly in the order they are supplied. If an early guard calls `next()` with an argument (e.g., a path to redirect to), subsequent guards in the `multiguard` chain will be bypassed, and the route will not be entered. Ensure critical checks are placed earlier in the array.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"For most scenarios, redirecting with `next('/some-path')` is preferred to provide explicit user feedback. Use `next(false)` only when completely halting navigation without an alternative path, and ensure your application's UI accounts for this scenario (e.g., by not attempting navigation again until user interaction).","message":"Calling `next(false)` inside any guard within `multiguard` will immediately cancel the current navigation without redirecting or resolving any route. This can lead to a 'stuck' state if not handled gracefully in the UI.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Upgrade to `vue-router-multiguard@^1.0.3` to leverage the included TypeScript definitions, or provide your own `.d.ts` declaration files if upgrading is not an option.","message":"TypeScript types for `vue-router-multiguard` were officially added in version 1.0.3. If you are working in a TypeScript project and using an older version (e.g., v1.0.2 or earlier), you will not have native type definitions available.","severity":"gotcha","affected_versions":"<1.0.3"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Change your import statement to `import multiguard from 'vue-router-multiguard';`. If using CommonJS `require`, ensure you access the default export correctly: `const multiguard = require('vue-router-multiguard').default;`","cause":"This error typically occurs when `multiguard` is imported incorrectly, often by using a named import syntax (`import { multiguard } from '...'`) for a module that provides a default export.","error":"TypeError: multiguard is not a function"},{"fix":"Ensure your guards' redirection logic only fires when necessary. Before calling `next(path)`, you might add a check like `if (to.path !== path) { next(path); } else { next(false); }` to prevent unnecessary navigation calls if already on the target path.","cause":"This warning (or similar) from Vue Router can appear if a guard redirects to the current route or attempts to push the same route multiple times consecutively. While not directly caused by `multiguard`, it's a common outcome of guard logic.","error":"NavigationDuplicated: Avoided redundant navigation to current location"}],"ecosystem":"npm"}