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
>
}
}Volar Plugins
To get the best TypeScript experience in Single File Components, add the following Volar plugins to your tsconfig.json (or tsconfig.app.json):
{
"vueCompilerOptions": {
"plugins": [
"vue-router/volar/sfc-route-blocks",
"vue-router/volar/sfc-typed-router",
],
},
}vue-router/volar/sfc-route-blocks— enables<route>blocks in SFCs for defining per-page route metadatavue-router/volar/sfc-typed-router— makesuseRoute()return a typed route based on the current page component, soroute.paramsis correctly typed
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))
}
)ESLint
If you use ESlint, check the ESlint section.

