SkillByAIOpen interactive version →

Lesson 17 / 25

Navigation Guards and Lazy Routes

Controlling and splitting navigation.

Guards and code splitting

Navigation guards run before a navigation is confirmed. A global router.beforeEach((to, from) => ...) can return false to cancel, a route location (such as { name: 'login' }) to redirect, or nothing / true to continue; it can also be async. Per-route beforeEnter and in-component guards like onBeforeRouteLeave (useful for unsaved-changes prompts) also exist. Lazy-loaded routes use component: () => import('./views/Settings.vue'), so the bundler splits each page into its own chunk that is downloaded only when the route is first visited. Older code passes a third next argument; returning a value is the current recommended style.

A global guard and lazy routes

Redirect and split chunks.

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

const router = createRouter({
  history: createWebHistory(),
  routes: [
    { path: '/', component: () => import('@/views/HomePage.vue') },
    { path: '/login', name: 'login', component: () => import('@/views/LoginPage.vue') },
    { path: '/settings', component: () => import('@/views/SettingsPage.vue') },
  ],
})

router.beforeEach(async (to) => {
  if (to.path === '/settings' && !(await isLoggedIn())) {
    return { name: 'login', query: { redirect: to.fullPath } }
  }
  // returning nothing allows the navigation
})

// Inside a component's <script setup>:
// import { onBeforeRouteLeave } from 'vue-router'
// onBeforeRouteLeave(() => {
//   if (hasUnsavedChanges.value) return window.confirm('Discard changes?')
// })

Guards are not security

Client-side guards improve the user experience, but anyone can bypass browser code. The API must still check authentication and authorisation on every request.

Quick check: What does returning false from a beforeEach guard do?

  • Redirects to the home route
  • Reloads the page
  • Cancels the navigation
  • Skips the remaining guards and continues
Answer

Cancels the navigation — Return a route location to redirect instead.