How to protect routes in Vue

Protecting routes based on authentication and authorization is essential for secure Vue applications, ensuring only authorized users can access restricted pages. As the creator of CoreUI, a widely used open-source UI library, I’ve implemented route protection 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 navigation guards with authentication checks. This pattern provides flexible access control and seamless user redirection.

Use navigation guards with beforeEnter or global beforeEach guards to check authentication before allowing route access.

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, role: 'admin' }
  }
]

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

// Global guard for all protected routes
router.beforeEach((to, from, next) => {
  if (to.meta.requiresAuth && !isAuthenticated()) {
    next('/login')
  } else if (to.meta.role && !hasRole(to.meta.role)) {
    next('/unauthorized')
  } else {
    next()
  }
})

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

function hasRole(requiredRole) {
  const userRole = localStorage.getItem('userRole')
  return userRole === requiredRole
}

Navigation guards execute before route navigation completes, allowing you to check authentication status and redirect unauthorized users. The beforeEnter guard protects individual routes, while beforeEach provides global protection. Use route meta fields to define access requirements like authentication and roles. The next() function controls navigation - call it without arguments to proceed, with a path to redirect, or false to cancel navigation.

This is the same route protection pattern we use in CoreUI Vue admin templates for secure dashboard access and role-based navigation. For complex authentication flows, consider using a dedicated authentication store with Vuex or Pinia to centralize user state management and permission checks.


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.

Answers by CoreUI Core Team