On this page
Vue Router
Vue Router is the official routing library for Vue SPAs. It maps URLs to components without full page reloads.
Installation
npm install vue-router@4
Basic Setup
src/router/index.js:
import { createRouter, createWebHistory } from 'vue-router';
import Home from '../views/Home.vue';
import About from '../views/About.vue';
const routes = [
{ path: '/', name: 'home', component: Home },
{ path: '/about', name: 'about', component: About },
{ path: '/:pathMatch(.*)*', name: 'not-found', component: () => import('../views/NotFound.vue') },
];
export default createRouter({
history: createWebHistory(),
routes,
});
Register in main.js:
import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
createApp(App).use(router).mount('#app');
App Layout with RouterView
src/App.vue:
<script setup>
import { RouterLink, RouterView } from 'vue-router';
</script>
<template>
<nav>
<RouterLink to="/">Home</RouterLink>
<RouterLink to="/about">About</RouterLink>
</nav>
<RouterView />
</template>
Route Parameters
{ path: '/users/:id', name: 'user', component: UserProfile }
<!-- views/UserProfile.vue -->
<script setup>
import { ref, watch } from 'vue';
import { useRoute } from 'vue-router';
const route = useRoute();
const user = ref(null);
watch(
() => route.params.id,
async (id) => {
const res = await fetch(`/api/users/${id}`);
user.value = await res.json();
},
{ immediate: true }
);
</script>
<template>
<h1 v-if="user">{{ user.name }}</h1>
<p v-else>Loading...</p>
</template>
Programmatic Navigation
<script setup>
import { useRouter } from 'vue-router';
const router = useRouter();
function goToDashboard() {
router.push('/dashboard');
}
</script>
Navigation Guards
Protect routes with a beforeEach guard:
router.beforeEach((to, from, next) => {
const isLoggedIn = localStorage.getItem('token');
if (to.meta.requiresAuth && !isLoggedIn) {
next({ name: 'login' });
} else {
next();
}
});
{ path: '/dashboard', component: Dashboard, meta: { requiresAuth: true } }
Lazy Loading
Use dynamic imports for code splitting:
{
path: '/admin',
component: () => import('../views/Admin.vue'),
}
Vue Router is the standard for Vue SPAs — pair it with Pinia for shared application state.