Vue 3 - Redirect to Login Page if Unauthenticated
Tutorial built with Vue 3.2.33 and Vue Router 4.0.15
This is a quick post to show how to redirect users to the login page in a Vue 3 app that uses Vue Router. The redirect applies to users that attempt to access a secure/restricted page when they are not logged in.
The below code files are part of a Vue 3 JWT authentication tutorial I posted recently that includes a live demo, so to see the code running check out Vue 3 + Pinia - JWT Authentication Tutorial & Example.
Vue 3 Router
The router defines the routes for the Vue 3 application and creates a new Vue Router instance with the createRouter()
function. The exported router
instance is imported into main.js where it is passed to the Vue app on startup.
The createRouter()
function is part of Vue Router v4 which is compatible with Vue 3, the previous version of the router (Vue Router v3) is compatible with Vue 2. For more info on what's changed in the new version of the Vue Router see https://next.router.vuejs.org/guide/migration/.
The home route maps the root path ('/'
) of the app to the HomeView
component and the '/login'
route maps to the LoginView
component.
Redirect to login from router beforeEach()
Unauthenticated users are prevented from accessing restricted pages by the function passed to router.beforeEach()
. If the user is not logged in and trying to access a secure page, the function returns the string '/login'
to redirect them to the login page. The requested path (to.fullPath
) is assigned to the Pinia auth store property auth.returnUrl
so the login page can redirect the user back their desired page after successful login.
For more information on Vue routing see https://router.vuejs.org/.
import { createRouter, createWebHistory } from 'vue-router';
import { useAuthStore } from '@/stores';
import { HomeView, LoginView } from '@/views';
export const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
linkActiveClass: 'active',
routes: [
{ path: '/', component: HomeView },
{ path: '/login', component: LoginView }
]
});
router.beforeEach(async (to) => {
// redirect to login page if not logged in and trying to access a restricted page
const publicPages = ['/login'];
const authRequired = !publicPages.includes(to.path);
const auth = useAuthStore();
if (authRequired && !auth.user) {
auth.returnUrl = to.fullPath;
return '/login';
}
});
Vue 3 Main.js
The main.js file bootstraps the Vue application by mounting the App
component in the #app
div element defined in the main index.html
file.
Vue routes are configured with the call to app.use(router)
, routes are defined in router.js.
Pinia support is added to the Vue app with the line app.use(createPinia())
.
import { createApp } from 'vue';
import { createPinia } from 'pinia';
import App from './App.vue';
import { router } from './helpers';
// setup fake backend
import { fakeBackend } from './helpers';
fakeBackend();
const app = createApp(App);
app.use(createPinia());
app.use(router);
app.mount('#app');
Vue 3 App Component
The App
component is the root component of the example Vue 3 + Pinia app, it contains the main nav bar which is only displayed for authenticated users, and a RouterView
component for displaying the contents of each view based on the current route / path.
The user
state property of the Pinia auth
store is used to reactively show/hide the main nav bar when the user logs in/out of the application.
The authStore.logout()
method is called from the logout link in the main nav bar to log the user out and redirect to the login page.
<script setup>
import { RouterLink, RouterView } from 'vue-router';
import { useAuthStore } from '@/stores';
const authStore = useAuthStore();
</script>
<template>
<div class="app-container bg-light">
<nav v-show="authStore.user" class="navbar navbar-expand navbar-dark bg-dark">
<div class="navbar-nav">
<RouterLink to="/" class="nav-item nav-link">Home</RouterLink>
<a @click="authStore.logout()" class="nav-item nav-link">Logout</a>
</div>
</nav>
<div class="container pt-4 pb-4">
<RouterView />
</div>
</div>
</template>
<style>
@import '@/assets/base.css';
</style>
Need Some Vue 3 Help?
Search fiverr for freelance Vue 3 developers.
Follow me for updates
When I'm not coding...
Me and Tina are on a motorcycle adventure around Australia.
Come along for the ride!