Introduction
Installation
Install using your favorite package manager:
npm install -D unplugin-vue-router
Add the plugin to your bundler:
import VueRouter from 'unplugin-vue-router/vite'
export default defineConfig({
plugins: [
VueRouter({
/* options */
}),
// ⚠️ Vue must be placed after VueRouter()
Vue(),
],
})
import VueRouter from 'unplugin-vue-router/rollup'
export default {
plugins: [
VueRouter({
/* options */
}),
// ⚠️ Vue must be placed after VueRouter()
Vue(),
],
}
module.exports = {
/* ... */
plugins: [
require('unplugin-vue-router/webpack')({
/* options */
}),
],
}
module.exports = {
configureWebpack: {
plugins: [
require('unplugin-vue-router/webpack')({
/* options */
}),
],
},
}
import { build } from 'esbuild'
import VueRouter from 'unplugin-vue-router/esbuild'
build({
plugins: [VueRouter()],
})
Setup
After adding this plugin, start the dev server (usually npm run dev
) to generate the first version of the types at typed-router.d.ts
which should be added to your tsconfig.json
along with "moduleResolution": "Bundler"
. This is what it should look like:
{
"include": [
// other files...
"./typed-router.d.ts"
],
"compilerOptions": {
// ...
"moduleResolution": "Bundler",
// ...
}
}
/* eslint-disable */
/* prettier-ignore */
// @ts-nocheck
// Generated by unplugin-vue-router. ‼️ DO NOT MODIFY THIS FILE ‼️
// It's recommended to commit this file.
// Make sure to add this file to your tsconfig.json file as an "includes" or "files" entry.
declare module 'vue-router/auto-routes' {
import type {
RouteRecordInfo,
ParamValue,
ParamValueOneOrMore,
ParamValueZeroOrMore,
ParamValueZeroOrOne,
} from 'unplugin-vue-router/types'
/**
* Route name map generated by unplugin-vue-router
*/
export interface RouteNamedMap {
'/': RouteRecordInfo<'/', '/', Record<never, never>, Record<never, never>>,
'/about': RouteRecordInfo<'/about', '/about', Record<never, never>, Record<never, never>>,
'/users/[id]': RouteRecordInfo<'/[id]', '/:id', { id: ParamValue<true> }, { id: ParamValue<false> }>,
}
}
Then, if you have an env.d.ts
file like the one created by npm vue create <my-project>
, add the unplugin-vue-router/client
types to it:
/// <reference types="vite/client" />
/// <reference types="unplugin-vue-router/client" />
If you don't have an env.d.ts
file, you can create one and add the unplugin-vue-router types to it or you can add them to the types
property in your tsconfig.json
:
{
"compilerOptions": {
// ...
"types": [
"unplugin-vue-router/client"
]
}
}
Instead of importing from vue-router
, you should import from vue-router/auto
.
TIP
You can exclude vue-router
from VSCode import suggestions by adding this setting to your .vscode/settings.json
:
{
"typescript.tsdk": "node_modules/typescript/lib",
"typescript.preferences.autoImportFileExcludePatterns": ["vue-router$"]
}
This will ensure VSCode only suggests vue-router/auto
for imports. Alternatively, you can also configure auto imports.
The reason we need to import from vue-router/auto
rather than vue-router
is because we override all the types with typed version. It is not possible to override the types from vue-router
directly as the typed ones are all generic.
Migrating an existing project
Move your page components to src/pages
and rename them accordingly. Here is an example of migration. Given the following route configuration:
import { createRouter, createWebHistory } from 'vue-router'
import { createRouter, createWebHistory } from 'vue-router/auto'
export const router = createRouter({
history: createWebHistory(),
routes: [
{
path: '/',
component: () => import('src/pages/Home.vue'),
},
{
path: '/users/:id',
component: () => import('src/pages/User.vue'),
}
{
path: '/about',
component: () => import('src/pages/About.vue'),
},
]
})
import { createApp } from 'vue'
import { router } from './router'
import App from './App.vue'
createApp(App).use(router).mount('#app')
- Rename
src/pages/Home.vue
tosrc/pages/index.vue
- Rename
src/pages/User.vue
tosrc/pages/users/[id].vue
- Rename
src/pages/About.vue
tosrc/pages/about.vue
Check the file-based routing guide for more information about the naming conventions.
From scratch
- Create a
src/pages
folder and add anindex.vue
component to it. This will render your home page at/
. - Add Vue Router using
vue-router/auto
instead ofvue-router
. These types are augmented to be fully typed.
import { createApp } from 'vue'
import { createRouter, createWebHistory } from 'vue-router/auto'
import App from './App.vue'
const router = createRouter({
history: createWebHistory(),
// the routes property is handled by the plugin
})
createApp(App)
.use(router)
.mount('#app')
<template>
<h1>Home</h1>
</template>
Check the file-based routing guide for more information about the naming conventions.
Passing the routes manually
Alternatively, you can also import the routes
array and create the router manually or pass it to some plugin. Here is an example with Vitesse starter:
import { ViteSSG } from 'vite-ssg'
import { setupLayouts } from 'virtual:generated-layouts'
import App from './App.vue'
import type { UserModule } from './types'
import generatedRoutes from '~pages'
import { routes } from 'vue-router/auto-routes'
import '@unocss/reset/tailwind.css'
import './styles/main.css'
import 'uno.css'
const routes = setupLayouts(generatedRoutes)
// https://github.com/antfu/vite-ssg
export const createApp = ViteSSG(
App,
{
routes,
routes: setupLayouts(routes),
base: import.meta.env.BASE_URL,
},
(ctx) => {
// install all modules under `modules/`
Object.values(
import.meta.glob<{ install: UserModule }>('./modules/*.ts', {
eager: true,
})
).forEach((i) => i.install?.(ctx))
}
)
Auto Imports
If you are using unplugin-auto-import, make sure to remove the vue-router
preset and use the one exported by unplugin-vue-router
:
import { defineConfig } from 'vite'
import AutoImport from 'unplugin-auto-import/vite'
import { VueRouterAutoImports } from 'unplugin-vue-router'
export default defineConfig({
plugins: [
// other plugins
AutoImport({
imports: [
'vue-router',
VueRouterAutoImports,
],
}),
],
})
Note that the vue-router
preset might export less things than the one exported by unplugin-vue-router
so you might need to add any other imports you were relying on manually:
AutoImport({
imports: [
VueRouterAutoImports,
{
// add any other imports you were relying on
'vue-router/auto': ['useLink']
},
],
}),
If you use ESlint, check the ESlint section. If you use TypeScript or have a jsconfig.json
file, check the TypeScript section.