Vue Router Multiguard

1.0.3 · active · verified Sun Apr 19

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.

Common errors

Warnings

Install

Imports

Quickstart

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.

import Vue from 'vue';
import VueRouter, { RouteConfig } from 'vue-router';
import multiguard from 'vue-router-multiguard';

Vue.use(VueRouter);

// Example guard functions
const requireAuth = (to, from, next) => {
    const isAuthenticated = localStorage.getItem('userToken'); // Simulate auth check
    if (to.meta?.requiresAuth && !isAuthenticated) {
        console.log(`Guard 'requireAuth' blocked for ${to.path}: User not authenticated.`);
        next('/login'); // Redirect to login page
    } else {
        next(); // Proceed
    }
};

const requireAdmin = (to, from, next) => {
    const userRole = localStorage.getItem('userRole'); // Simulate role check
    if (to.meta?.requiresAdmin && userRole !== 'admin') {
        console.log(`Guard 'requireAdmin' blocked for ${to.path}: Not an administrator.`);
        next('/access-denied'); // Redirect for insufficient permissions
    } else {
        next(); // Proceed
    }
};

const logRoute = (to, from, next) => {
    console.log(`Guard 'logRoute' entered: ${from.path} -> ${to.path}`);
    next(); // Always proceed
};

const routes: Array<RouteConfig> = [
    {
        path: '/',
        component: { template: '<div><h1>Home</h1><p>Public access.</p></div>' },
        name: 'home'
    },
    {
        path: '/dashboard',
        component: { template: '<div><h1>Dashboard</h1><p>Authenticated access.</p></div>' },
        name: 'dashboard',
        meta: { requiresAuth: true },
        beforeEnter: multiguard([logRoute, requireAuth]) // Combined guards
    },
    {
        path: '/admin',
        component: { template: '<div><h1>Admin Panel</h1><p>Admin-only access.</p></div>' },
        name: 'admin',
        meta: { requiresAuth: true, requiresAdmin: true },
        beforeEnter: multiguard([logRoute, requireAuth, requireAdmin]) // Multiple combined guards
    },
    {
        path: '/login',
        component: { template: '<div><h1>Login</h1><p>Please log in.</p></div>' },
        name: 'login'
    },
    {
        path: '/access-denied',
        component: { template: '<div><h1>Access Denied</h1><p>You do not have permission to view this page.</p></div>' },
        name: 'access-denied'
    }
];

const router = new VueRouter({ routes });

// Simulate user state for demonstration
localStorage.setItem('userToken', 'fake-jwt-token-123'); // User is 'logged in'
localStorage.setItem('userRole', 'user'); // User is not 'admin'

console.log('--- Navigating to /dashboard (authenticated user) ---');
router.push('/dashboard').catch(err => console.error('Navigation error:', err.message));

setTimeout(() => {
    console.log('\n--- Navigating to /admin (authenticated but not admin) ---');
    router.push('/admin').catch(err => console.error('Navigation error:', err.message));
}, 100);

setTimeout(() => {
    console.log('\n--- Navigating to /dashboard (unauthenticated user) ---');
    localStorage.removeItem('userToken'); // Simulate logout
    router.push('/dashboard').catch(err => console.error('Navigation error:', err.message));
}, 200);

// For a real app, you'd mount this to a Vue instance:
// new Vue({ router, el: '#app' });

view raw JSON →