Getting Started
Vue Router includes a built-in file-based routing plugin. It generates the routes and types automatically from your page components, so you no longer need to maintain a routes array manually.
Setup
Add the plugin to your bundler:
import VueRouter from 'vue-router/vite'
export default defineConfig({
plugins: [
VueRouter({
/* options */
}),
// ⚠️ Vue must be placed after VueRouter()
Vue(),
],
})import VueRouter from 'vue-router/unplugin/rollup'
export default {
plugins: [
VueRouter({
/* options */
}),
// ⚠️ Vue must be placed after VueRouter()
Vue(),
],
}module.exports = {
/* ... */
plugins: [
require('vue-router/unplugin/webpack')({
/* options */
}),
],
}module.exports = {
configureWebpack: {
plugins: [
require('vue-router/unplugin/webpack')({
/* options */
}),
],
},
}import { build } from 'esbuild'
import VueRouter from 'vue-router/unplugin/esbuild'
build({
plugins: [VueRouter()],
})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 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 'vue-router'
/**
* Route name map generated by vue-router file-based routing
*/
export interface RouteNamedMap {
'/': RouteRecordInfo<
'/',
'/',
Record<never, never>,
Record<never, never>,
| never
>
'/about': RouteRecordInfo<
'/about',
'/about',
Record<never, never>,
Record<never, never>,
| never
>
'/users/[id]': RouteRecordInfo<
'/users/[id]',
'/users/:id',
{ id: ParamValue<true> },
{ id: ParamValue<false> },
| never
>
}
}Then, if you have an env.d.ts file, add the vue-router/auto types to it:
/// <reference types="vite/client" />
/// <reference types="vue-router/auto" />If you don't have an env.d.ts file, you can create one or add them to the types property in your tsconfig.json:
{
"compilerOptions": {
// ...
"types": [
"vue-router/auto"
]
}
}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 { routes, handleHotUpdate } from 'vue-router/auto-routes'
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'),
},
]
routes,
})
// This will update routes at runtime without reloading the page
if (import.meta.hot) {
handleHotUpdate(router)
} import { createApp } from 'vue'
import { router } from './router'
import App from './App.vue'
createApp(App).use(router).mount('#app')- Rename
src/pages/Home.vuetosrc/pages/index.vue - Rename
src/pages/User.vuetosrc/pages/users/[id].vue - Rename
src/pages/About.vuetosrc/pages/about.vue
Check the file conventions guide for more information about the naming conventions.
From scratch
- Create a
src/pagesfolder and add anindex.vuecomponent to it. This will render your home page at/. - Import the
routesfromvue-router/auto-routesand pass them to thecreateRouterfunction.
import { createApp } from 'vue'
import { createRouter, createWebHistory } from 'vue-router'
import { routes } from 'vue-router/auto-routes'
import App from './App.vue'
const router = createRouter({
history: createWebHistory(),
routes,
})
createApp(App)
.use(router)
.mount('#app')<template>
<h1>Home</h1>
</template>Check the file conventions guide for more information about the naming conventions.
Manipulating the routes
You can pass the routes to any plugin that needs to add changes to them but note that these changes will not be reflected in types. Use build-time routes instead if you want to have types support. 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 vue-router:
import { defineConfig } from 'vite'
import AutoImport from 'unplugin-auto-import/vite'
import { VueRouterAutoImports } from 'vue-router'
export default defineConfig({
plugins: [
// other plugins
AutoImport({
imports: [
'vue-router',
VueRouterAutoImports,
],
}),
],
})If you use ESlint, check the ESlint section.

