Vue.js Navigation Guards
Navigation guards are functions that run before or after a route change. They decide whether a visitor may enter a page, redirect to another page, or stop a move completely. Login checks, role checks, unsaved form warnings, and page analytics all rely on guards.
Picture a security desk at an office building. Every visitor stops at the desk before reaching a floor. The guard checks a badge and either waves the visitor through or points to the reception area. A navigation guard performs that check for every route change.
Global Guard with beforeEach
The beforeEach guard runs before every navigation. It receives the destination route (to) and the starting route (from). Returning nothing or true allows the move. Returning false cancels it. Returning a route location redirects.
// router.js
router.beforeEach((to, from) => {
const loggedIn = Boolean(localStorage.getItem("token"));
if (to.path === "/account" && !loggedIn) {
return "/login";
}
});Diagram: Guard Decision
Visitor clicks "/account"
|
v
beforeEach(to, from)
|
logged in? --yes--> allow, page opens
|
no
|
v
redirect to /loginProtect Many Routes with Meta Fields
Checking path names one by one becomes clumsy. A meta object on each route carries custom labels, and one guard reads the labels.
const routes = [
{ path: "/", component: Home },
{ path: "/login", component: Login },
{ path: "/account", component: Account, meta: { requiresAuth: true } },
{ path: "/orders", component: Orders, meta: { requiresAuth: true } }
];
router.beforeEach((to) => {
const loggedIn = Boolean(localStorage.getItem("token"));
if (to.meta.requiresAuth && !loggedIn) {
return { path: "/login", query: { redirect: to.fullPath } };
}
});The redirect carries the original address in a query value. After a successful login, the login page reads route.query.redirect and sends the visitor to the page they wanted.
Diagram: Meta Labels
/ meta: none --> open to everyone /login meta: none --> open to everyone /account meta: requiresAuth --> guard checks login /orders meta: requiresAuth --> guard checks login
Per-Route Guard with beforeEnter
A guard can live on a single route when only that page needs a check.
{
path: "/admin",
component: AdminPanel,
beforeEnter: (to, from) => {
const role = localStorage.getItem("role");
if (role !== "admin") return "/";
}
}Guards Inside Components
Composition API components use onBeforeRouteLeave and onBeforeRouteUpdate. The leave guard protects unsaved work.
<script setup>
import { ref } from "vue";
import { onBeforeRouteLeave } from "vue-router";
const unsaved = ref(false);
onBeforeRouteLeave(() => {
if (unsaved.value) {
return window.confirm("Leave without saving?");
}
});
</script>A visitor who clicks away from a half-finished form sees a confirmation box. Choosing Cancel returns false and keeps the visitor on the page.
Run Code After Navigation with afterEach
The afterEach hook fires once the move is complete. It cannot cancel navigation, which makes it ideal for page titles and analytics.
router.afterEach((to) => {
document.title = to.meta.title || "My Site";
});Order of Execution
Diagram: Guard Sequence
1. beforeRouteLeave (component being left) 2. beforeEach (global) 3. beforeEnter (route config) 4. component is created 5. afterEach (global, after the move)
Handle Async Checks
Guards may be async functions. The router waits for the result before continuing, which suits checks that call a server.
router.beforeEach(async (to) => {
if (to.meta.requiresAuth) {
const valid = await checkSession();
if (!valid) return "/login";
}
});Security Reminder
Guards control what the browser shows. They do not protect data. Anyone can change browser storage or call an API directly. Always verify permissions on the server for every request that returns private data.
Summary
Navigation guards intercept route changes. beforeEach checks every move, meta fields label protected pages, beforeEnter guards one route, and onBeforeRouteLeave protects unsaved work. afterEach handles titles and tracking. Returning false cancels, returning a location redirects, and server-side checks remain essential for real security.
