How to add route guards in Vue

Route guards provide fine-grained control over navigation in Vue applications, enabling authentication checks, permission validation, and conditional routing logic. As the creator of CoreUI, a widely used open-source UI library, I’ve implemented route guards in numerous Vue admin dashboards and enterprise applications. From my 25 years of experience in web development and 11 years with Vue, the most effective approach is to use Vue Router’s built-in navigation guards with clear authentication and authorization logic. This pattern provides flexible access control and seamless user experience.

Use navigation guards like beforeEach, beforeEnter, and beforeRouteEnter to control route access based on authentication and permissions.

import { createRouter, createWebHistory } from 'vue-router'

const routes = [
  {
    path: '/login',
    component: () => import('./views/Login.vue')
  },
  {
    path: '/dashboard',
    component: () => import('./views/Dashboard.vue'),
    beforeEnter: (to, from, next) => {
      if (isAuthenticated()) {
        next()
      } else {
        next('/login')
      }
    }
  },
  {
    path: '/admin',
    component: () => import('./views/Admin.vue'),
    meta: { requiresAuth: true, roles: ['admin'] }
  }
]

const router = createRouter({
  history: createWebHistory(),
  routes
})

// Global navigation guard
router.beforeEach((to, from, next) => {
  if (to.meta.requiresAuth) {
    if (!isAuthenticated()) {
      next('/login')
      return
    }

    if (to.meta.roles && !hasRequiredRole(to.meta.roles)) {
      next('/unauthorized')
      return
    }
  }

  next()
})

function isAuthenticated() {
  return !!localStorage.getItem('authToken')
}

function hasRequiredRole(requiredRoles) {
  const userRole = localStorage.getItem('userRole')
  return requiredRoles.includes(userRole)
}

Navigation guards execute at different points in the route transition: beforeEach runs globally before every route change, beforeEnter runs for specific routes, and beforeRouteEnter runs in components. Use route meta fields to define access requirements declaratively. The next() function controls navigation flow - call with no arguments to proceed, with a path to redirect, or false to cancel navigation. Combine guards with authentication state management for robust access control.

This is the same route guard pattern we use in CoreUI Vue admin templates for secure dashboard access and role-based navigation control. For complex authorization logic, consider using a dedicated permission system with Vuex or Pinia to centralize access control decisions and user role management.


Speed up your responsive apps and websites with fully-featured, ready-to-use open-source admin panel templates—free to use and built for efficiency.


About the Author

Subscribe to our newsletter
Get early information about new products, product updates and blog posts.
How to Merge Objects in JavaScript
How to Merge Objects in JavaScript

How to limit items in a .map loop in JavaScript
How to limit items in a .map loop in JavaScript

What Does javascript:void(0) Mean?
What Does javascript:void(0) Mean?

How to concatenate a strings in JavaScript?
How to concatenate a strings in JavaScript?

Answers by CoreUI Core Team