Unplugin Vue Router is a plugin for Vue.js that allows you to automatically generate file-based routing.
File-based routing is a pattern that automates the generation of routes based on the directory structure of your project.
That is, the folder and file structure directly reflects the navigation of your application. This eliminates the need to manually maintain route configuration files.
It is similar to the way frameworks like Nuxt.js or Next.js work, but without the need for a meta-framework.
Installation and Basic Configuration
To install Unplugin Vue Router in our project (which already has Vue Router installed), we do the following.
npm install unplugin-vue-router --save-dev
Now to configure it
We add the plugin to the Vite configuration in vite.config.ts
import { defineConfig } from 'vite'
import Vue from '@vitejs/plugin-vue'
import VueRouter from 'unplugin-vue-router/vite'
export default defineConfig({
plugins: [
VueRouter({
routesFolder: 'src/pages', // Routes folder
}),
Vue(), // Important: Vue() must come after!
],
})
Now we initialize the plugin in main.ts
(or equivalent),
import { createApp } from 'vue'
import { createRouter, createWebHistory } from 'vue-router/auto' // Auto-imports the routes
const router = createRouter({
history: createWebHistory(),
// Routes are generated automatically!
})
const app = createApp(App)
app.use(router)
app.mount('#app')
Unplugin Vue Router maintains compatibility with Vue Router. It is not a replacement, but an extension.
Basic File Structure
Routes are automatically generated following simple conventions. For example,
src/
└── pages/
├── index.vue → /
├── contact.vue → /contact
└── about.vue → /about
In this case:
- The route / will take you to the
index.vue
component. - The route /contact will take you to the
contact.vue
component. - The route /about will take you to the
about.vue
component.
So easy 😉.
Nested Routes
Create subdirectories for nested routes. Each subdirectory within /pages
creates a new segment in the route. For example,
src/
└── pages/
├── welcome.vue → /welcome
└── dashboard/
├── settings.vue → /dashboard/settings
└── profile.vue → /dashboard/profile
In this case:
- The route /welcome will take you to
welcome.vue
. - The route /dashboard/settings will take you to
dashboard/settings.vue
. - The route /dashboard/profile will take you to
dashboard/profile.vue
.
The Special Case of Index in Routes
You may have noticed that index
has somewhat special behavior. This file represents the base route of its directory. With this structure:
src/
└── pages/
├── index.vue → /
└── dashboard/
└── index.vue → /dashboard
- The route / will take you to
index.vue
. - The route /dashboard will take you to
dashboard/index.vue
.
It is a very common behavior in routing, file servers, etc.
Dynamic Routes and Parameters
For dynamic routes and parameters, Unplugin Vue Router uses brackets as placeholders for parameters,
[param].vue
→ Dynamic route (e.g.,/users/123
)[...slug].vue
→ Catch-all route (e.g.,/docs/a/b/c
)
That is, the following folder structure
src/
└── pages/
└── users/
├── [id].vue → /users/:id
└── index.vue → /users
In this example, the routes for the user system will be automatically generated:
users/index.vue
→ Route/users
(user list).users/[id].vue
→ Dynamic route/users/:id
(details of a specific user).
You can use parameters in both file names and folder names, and combine them at any level of nesting to create the routes you need.
Accessing Parameters
We can access parameters in the same way we would normally with Vue Router. For example, for pages/users/[id].vue
<script setup lang="ts">
const route = useRoute('/users/[id]')
console.log(route.params.id) // Type inferred as string
</script>
Safe Typing
The plugin generates TypeScript types for all routes in typed-router.d.ts
, providing autocompletion and validation.
router.push('/users/123') // Autocompletion and validation
const { id } = route.params // Inferred type: `id: string`
Manually Extending Routes
We can also add additional routes in case we need to customize any of them. To do this, we can edit the routes.ts
file,
// src/routes.ts
import { extendRoutes } from 'unplugin-vue-router'
export default extendRoutes((routes) => {
routes.push({
path: '/custom',
component: () => import('./pages/custom.vue'),
meta: { requiresAuth: true }
})
})