VueJs - Customize simple middleware in vue-router

This post will introduce you to the concept of middleware in vue-router and provide a recipe for customizing it.

Middleware is a piece of software component that runs between router and component usually they use it to check authenticated user and permission authorization.

If a middleware does not meet certain conditions we can redirect to another URL. For example, if you require the user to log in to use for website, you can use middleware to check authenticated user and if the user does not authenticate you can redirect to the login page.

Create auth middleware

Checking for access tokens exist in local storage in ./src/middlewares/auth.js

If have an Access-Token in local storage we redirect the user to the dashboard (Note: This is just an example in reality if you want to check for authenticate if have an access-token you can redirect to next(), if not redirect to the login page)

export default function ({ next, router }) { 
    if(localStorage.getItem('Access-Token')) {
        router.push({ name: 'dashboard' });
    }

    return next();
}

Using middleware

In ./src/routes/index.js

import Vue from "vue";
import VueRouter from "vue-router";
import AuthMiddleware from "@/middlewares/auth";

Vue.use(VueRouter);

const router = new VueRouter({
    mode: "history",
    routes: [
        {
            path: '/',
            name: 'helloworld',
            component: () => import('@/components/HelloWorld'),
            meta: {
                middleware: AuthMiddleware
            }
        },
        {
            path: '/dashboard',
            name: 'dashboard',
            component: () => import('@/components/DashBoard')
        }
    ]
});

function nextFactory(context, middleware, index) {
    const subsequentMiddleware = middleware[index];
    return (...parameters) => {
        context.next(...parameters);
        subsequentMiddleware({ ...context, next: nextMiddleware });
    };
}
    
router.beforeEach((to, from, next) => {
    if (to.meta.middleware) {
    const middleware = Array.isArray(to.meta.middleware)
        ? to.meta.middleware
        : [to.meta.middleware];

    const context = {
        from,
        next,
        router,
        to,
    };
    const nextMiddleware = nextFactory(context, middleware, 1);

    return middleware[0]({ ...context, next: nextMiddleware });
    }

    return next();
});

export default router;

Sample template file

Helloworld vue file ./src/components/HelloWorld.vue

<template>
    <div><h5>Hello World</h5></div>
</template>

<script>
export default {
  
}
</script>

DashBoard vue file ./src/components/DashBoard.vue

<template>
    <div>
        <h5>Dashboard</h5>
    </div>
</template>

<script>
export default {
  
}
</script>

When accessing helloworld URL if in the browser have access token stored in local storage it will redirect to the dashboard.