Stores, actions, getters, and the Pinia patterns that replace Vuex for all new Vue 3 projects. Share state across components without prop drilling.
Stores, actions, getters, and the Pinia patterns that replace Vuex for all new Vue 3 projects. Share state across components without prop drilling.
npm install vue-router
import { createRouter, createWebHistory } from 'vue-router'
// Import page components
import HomeView from '@/views/HomeView.vue'
const routes = [
{
path: '/',
name: 'home',
component: HomeView
},
{
path: '/about',
name: 'about',
// Lazy-load: only downloaded when the route is visited
component: () => import('@/views/AboutView.vue')
},
{
path: '/users/:id', // :id is a dynamic segment
name: 'user-detail',
component: () => import('@/views/UserDetailView.vue')
},
{
// 404 catch-all — must be last
path: '/:pathMatch(.*)*',
name: 'not-found',
component: () => import('@/views/NotFoundView.vue')
}
]
const router = createRouter({
history: createWebHistory(), // uses real URLs (no #)
routes
})
export default router
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import router from './router'
import App from './App.vue'
createApp(App).use(createPinia()).use(router).mount('#app')
Dynamic route segments like :id let one route match many URLs. Access the current route's params, query, and path with useRoute().
Loading user {{ route.params.id }}...
{{ user.name }}
{{ user.email }}
Navigation guards run code before a route is entered — perfect for authentication checks.
import { useAuthStore } from '@/stores/auth'
// Per-route guard using route metadata
const routes = [
{
path: '/dashboard',
component: () => import('@/views/DashboardView.vue'),
meta: { requiresAuth: true } // mark protected routes
}
]
// Global guard: runs before every navigation
router.beforeEach((to, from) => {
const auth = useAuthStore()
if (to.meta.requiresAuth && !auth.isLoggedIn) {
// Redirect to login, saving where they wanted to go
return { name: 'login', query: { redirect: to.fullPath } }
}
})
route.query.redirect || '/' so they land on the page they originally tried to visit. This is the expected UX pattern./users/:id), and 404.https://jsonplaceholder.typicode.com/users and display them on the Users page.RouterLink and active link styling.() => import('./View.vue') for better initial load performance.:id let one route serve many URLs. Read them with useRoute().params.router.push() for programmatic navigation, RouterLink in templates.The foundations from today carry directly into Day 5. In the next session the focus shifts to Testing and Deployment — building directly on everything covered here.
Before moving on, verify you can answer these without looking:
Live Bootcamp
Learn this in person — 2 days, 5 cities
Thu–Fri sessions in Denver, Los Angeles, New York, Chicago, and Dallas. $1,490 per seat. June–October 2026.
Reserve Your Seat →