Basic Route Setup

// src/route/index.ts

const router = createRouter({
  ...
  routes: [
    {
      path: '/',
      name: 'home', // "home" will be route name
      component: () => import('./views/HomeView.vue') // Always lazy load route components
    },
    {
      path: '/about',
      name: 'about',
      component: () => import('./views/About.vue')
    }
  ]
})

Use RouterView to render the matched component for the current route, and use RouterLink component to create links to navigate between routes.

<template>
 <nav>
   <RouterLink to="/">Home</RouterLink>

   <!-- Use route name via object syntax -->
   <RouterLink :to="{ name: 'about' }">About</RouterLink>
 </nav>
 <RouterView />
</template>

Programmatic Navigation

Aside from using <RouterLink> to create anchor tags for declarative navigation, we can do this programmatically using the router's instance methods.

Declarative Programmatic
<RouterLink :to="..."> router.push(...)
<RouterLink :to="..." replace> router.replace(...)
window.history.go(n) router.go(1)

The argument can be a string path, or a location descriptor object.

// literal string path
router.push('/users/eduardo')

// object with path
router.push({ path: '/users/eduardo' })

// named route with params to let the router build the url
router.push({ name: 'user', params: { username: 'eduardo' } })

// with query, resulting in /register?plan=private
router.replace({ path: '/register', query: { plan: 'private' } })

// with hash, resulting in /about#team
router.replace({ path: '/about', hash: '#team' })

// go forward by one record, the same as router.forward()
router.go(1)

// go back by one record, the same as router.back()
router.go(-1)

Dynamic Routing

Dynamic routes are used to match a series of routes with some params to be acquired. (Denoted by colon : )

// src/router/index.ts

const router = createRouter({
  ...
  routes: [
    {
      path: '/product/:id', // [!code highlight]
      name: 'product',
      component: () => import('./views/ProductView.vue')
    }
  ]
})
<!-- src/views/ProductView.vue -->

<script setup>
  import { useRoute } from 'vue-router'
  const products = [
      { id: 1, name: Computer },
      { id: 2, name: Laptop },
      ...
  ]

  const route = useRoute()
  const product = products.find(p => p.id === parseInt(route.params.id))
</script>

<template>
 <main>
    <h1>{{ product.name }}</h1>
 </main>
</template>

Catch all / 404 Not found Route

const router = createRouter({
  ...
  routes: [
    // will match everything and put it under `$route.params.pathMatch`
    {
      path: '/:pathMatch(.*)*',
      name: 'NotFound',
      component: () => import('./views/NotFound.vue')  // Component
    },
    // will match anything starting with `/user-` and put it under `$route.params.afterUser`
    {
      path: '/user-:afterUser(.*)',
      component: () => import('./views/UserGeneric.vue')  // Component
    }
  ]
})

Routes' Matching Syntax

const routes = [
  // matches /o/3549 or /o/books
  { path: '/o/:orderId' },

  // /:orderId -> matches only numbers
  { path: '/:orderId(\\\\\\\\d+)' },

  // /:productName -> matches anything else
  { path: '/:productName' },

  // /:chapters -> matches /one, /one/two, /one/two/three, etc
  { path: '/:chapters+' },

  // /:chapters -> matches /, /one, /one/two, /one/two/three, etc
  { path: '/:chapters*' },

  // Sensitive and strict route options: match /users/posva but not:
  // - /Users/posva because of sensitive: true
  { path: '/users/:id', sensitive: true },

  // - /users/posva/ because of strict: true
  { path: '/users/:id?', strict: true },

  // Optional parameters: match /users and /users/posva
  { path: '/users/:userId?' },
]

Nested Routes

It is used when components that are nested with multiple levels deep.

/user/johnny/profile                     /user/johnny/posts
+------------------+                  +-----------------+
| User             |                  | User            |
| +--------------+ |                  | +-------------+ |
| | Profile      | |  +------------>  | | Posts       | |
| |              | |                  | |             | |
| +--------------+ |                  | +-------------+ |
+------------------+                  +-----------------+