Vue Route Middleware
raw JSON →`vue-route-middleware` is a lightweight utility for Vue.js applications designed to streamline and enhance the management of route middleware logic within `vue-router`. It simplifies the definition and execution of complex global route guards, offering both inline function and chainable middleware arrays directly within route meta fields. The library is currently stable at version 1.0.7, with its last major release (v1.0.0) providing the core functionality, followed by minor updates. Its primary differentiator is the ability to define middleware either as direct functions, an array of functions for chaining, or as named functions referenced from an object passed to `VueRouteMiddleware()`, allowing for flexible application across different router guards like `beforeEach` and `afterEach`. It promotes clean, readable route configurations by abstracting complex guard logic, making it easier to manage permissions, tracking, and other route-specific concerns. It does not introduce breaking changes frequently, focusing on stability within the 1.x series.
Common errors
error Navigation aborted with a different navigation. Or: Navigation failed because a redirect occurred. ↓
next({ name: 'Login' })), it immediately return false; to prevent other middlewares in the chain from executing and potentially causing further navigation actions. error TypeError: Cannot read properties of undefined (reading 'meta') (or similar for missing middleware execution) ↓
router.beforeEach(VueRouteMiddleware()); or router.beforeEach(VueRouteMiddleware({ AuthMiddleware, PaymentMiddleware })); is present in your router setup, and that all named middlewares referenced in meta.middleware are included in the object passed to VueRouteMiddleware. error ReferenceError: [YourMiddlewareName] is not defined ↓
AuthMiddleware from its respective file (e.g., import AuthMiddleware from './route/middleware/auth';) and then include it in the object passed to the VueRouteMiddleware initializer: router.beforeEach(VueRouteMiddleware({ AuthMiddleware })); Warnings
gotcha To halt the execution of subsequent middlewares in a chain, a middleware function must explicitly `return false`. If `false` is not returned, the chain will continue to execute, even if a redirect (`next({ name: '...' })`) has been triggered. ↓
gotcha Compatibility with Vue Router versions: This library is designed for Vue 2 and Vue Router 3. For Vue 3 applications, which use Vue Router 4, the router guard API has changed. Direct compatibility is not guaranteed, and you may need to adapt your middleware logic or consider alternatives built specifically for the Vue 3 ecosystem. ↓
gotcha Middleware functions, especially those used with `beforeEach`, must always call `next()` (or `next(false)`, `next('/path')`, etc.) or explicitly `return false` if the chain should stop. Failure to do so will leave the navigation pending indefinitely, leading to a stuck user experience. ↓
Install
npm install vue-route-middleware yarn add vue-route-middleware pnpm add vue-route-middleware Imports
- VueRouteMiddleware wrong
import { VueRouteMiddleware } from 'vue-route-middleware';correctimport VueRouteMiddleware from 'vue-route-middleware'; - AuthMiddleware (example)
import AuthMiddleware from './path/to/authMiddleware';
Quickstart
import Vue from 'vue';
import VueRouter from 'vue-router';
import VueRouteMiddleware from 'vue-route-middleware';
Vue.use(VueRouter);
// Simulate user login status and payment status
const fakeUser = {
isLogged: () => localStorage.getItem('isLoggedIn') === 'true',
madePayment: () => localStorage.getItem('hasPaid') === 'true'
};
// Define dummy components
const Dashboard = { template: '<div><h1>Dashboard</h1><p>Welcome, {{ isLoggedIn ? "User" : "Guest" }}!</p></div>' };
const Login = { template: '<div><h1>Login Page</h1><p>Set isLoggedIn=true in localStorage to proceed.</p></div>' };
const Payment = { template: '<div><h1>Payment Page</h1><p>Set hasPaid=true in localStorage to proceed.</p></div>' };
const Home = { template: '<div><h1>Home Page</h1><p>Navigate to /dashboard.</p></div>' };
// Define middleware functions
const AuthMiddleware = (to, from, next) => {
console.log('Running AuthMiddleware...');
if (!fakeUser.isLogged()) {
next({ name: 'Login' }); // Redirect to login
return false; // Crucial: stop middleware chain
}
next(); // Continue if authenticated
};
const PaymentMiddleware = (to, from, next) => {
console.log('Running PaymentMiddleware...');
if (!fakeUser.madePayment()) {
next({ name: 'Payment' }); // Redirect to payment
return false; // Crucial: stop middleware chain
}
next(); // Continue if payment made
};
const routes = [
{ path: '/', name: 'Home', component: Home },
{
path: '/dashboard',
name: 'Dashboard',
component: Dashboard,
meta: {
middleware: ['AuthMiddleware', 'PaymentMiddleware'] // Apply named middlewares
}
},
{ path: '/login', name: 'Login', component: Login },
{ path: '/payment', name: 'Payment', component: Payment }
];
const router = new VueRouter({
mode: 'history',
routes
});
// Initialize vue-route-middleware with named middlewares
router.beforeEach(VueRouteMiddleware({ AuthMiddleware, PaymentMiddleware }));
// Create and mount the Vue app (for a full runnable example)
// new Vue({
// router,
// template: `
// <div id="app">
// <router-link to="/">Home</router-link> |
// <router-link to="/dashboard">Dashboard</router-link> |
// <router-link to="/login">Login</router-link> |
// <router-link to="/payment">Payment</router-link>
// <hr>
// <router-view></router-view>
// </div>
// `
// }).$mount('#app');
// To test, open your browser console and set:
// localStorage.setItem('isLoggedIn', 'true');
// localStorage.setItem('hasPaid', 'true');
// Then navigate to /dashboard.