File-based routing (vue-router@5.3.1)
The bundler plugin generates the routes array and types from a pages folder. In v5 it ships inside vue-router; no separate unplugin-vue-router install.
Setup per bundler
// vite.config.ts
import VueRouter from 'vue-router/vite'
import Vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [VueRouter(), Vue()], // Vue plugin MUST come after VueRouter
})// rollup
import VueRouter from 'vue-router/unplugin/rollup'
// webpack
require('vue-router/unplugin/webpack')
// esbuild
import VueRouter from 'vue-router/unplugin/esbuild'
// rolldown
import VueRouter from 'vue-router/unplugin/rolldown'Entry points exist in package.json:104-114 and dist/unplugin/.
Router setup
import { createRouter, createWebHistory } from 'vue-router'
import { routes, handleHotUpdate } from 'vue-router/auto-routes'
const router = createRouter({ history: createWebHistory(), routes })
if (import.meta.hot) handleHotUpdate(router) // optional callback: (newRoutes) => {}vue-router/auto-routes is a virtual module generated by the plugin (vue-router-auto-routes.d.mts:6-31). Runtime mutations of the routes array work but are invisible to types; prefer build-time extension (below).
Generated types
- Default output:
typed-router.d.tsat project root (dist/unplugin-C2XPnbvD.mjs:2394); configure withdts: 'src/types/routes.d.ts'or disable withdts: false. - Add it to
tsconfig.jsonincludeand set"moduleResolution": "Bundler". - Commit the file. It wires
TypesConfig.RouteNamedMapto theRouteNamedMapinterface declared onvue-router/auto-routes, plus_RouteFileInfoMapused by the Volar plugin (dist/unplugin-C2XPnbvD.mjs:1661-1672). - Volar plugins for SFCs (in
tsconfig.json):
{
"vueCompilerOptions": {
"plugins": ["vue-router/volar/sfc-route-blocks", "vue-router/volar/sfc-typed-router"]
}
}sfc-route-blocks enables <route> blocks; sfc-typed-router types useRoute() per page file (since v5.1.0 it also narrows typeof useRoute, https://github.com/vuejs/router/releases/tag/v5.3.0).
File naming conventions (folder src/pages by default)
| File | Route |
|---|---|
index.vue |
/ (folder root) |
about.vue |
/about |
users/index.vue |
/users |
users/[id].vue |
/users/:id |
users/[id=int].vue |
/users/:id parsed as number (needs param parsers) |
users/[[id]].vue |
/users/:id? optional |
articles/[slugs]+.vue |
/articles/:slugs+ repeatable |
articles/[[slugs]]+.vue |
/articles/:slugs* optional repeatable |
[...path].vue |
/:path(.*) catch-all |
users.create.vue |
/users/create, sibling of users/ (dot nests the URL without layout nesting) |
index@aux.vue |
named view aux of / |
(admin)/dashboard.vue |
/dashboard (group folder: organizes files, no URL segment) |
(dashboard).vue |
acts as index.vue of its folder |
users.vue next to users/ |
makes users/index.vue a nested child rendered in users.vue's <RouterView> |
_parent.vue in a folder |
layout parent for that folder, non-matchable by default (since v5.0.3) |
- Every route with a component gets a generated
namederived from its file path; override withgetRouteNameordefinePage({ name }). indexmust be all lowercase.
definePage() macro
Add route properties from inside the page component. Globally available in SFCs; also declared on vue-router/auto-routes (vue-router-auto-routes.d.mts:51-53).
<script setup lang="ts">
definePage({
name: 'user-detail', // or false to make the route anonymous
alias: ['/u/:id'],
meta: { requiresAuth: true },
params: { // experimental, needs experimental.paramParsers
path: { id: 'int' }, // parser for a path param of this file
query: {
page: { parser: 'int', default: 1, format: 'value', required: false },
},
},
})
</script>Constraints (build-time extraction):
- Only static values; referencing
<script setup>bindings fails (diagnostic VUE_ROUTER_B0021). - One call per file; duplicates are reported, not crashed (since v5.3.0).
- No
beforeEnter(functions cannot be extracted). Use a global guard withmeta, or extend at runtime. - Changes are reflected in the generated
typed-router.d.ts.
DefinePageQueryParamOptions fields: parser, default, format: 'value' | 'array', required (dist/index-D7ja2BKs.d.ts:1754-1783).
<route> custom block
<route lang="json5">
{ meta: { requiresAuth: true } }
</route>Block language configurable with routeBlockLang: 'yaml' | 'yml' | 'json5' | 'json' (default json5). Requires the sfc-route-blocks Volar plugin for editor support.
Build-time route extension
VueRouter({
extendRoute(route) {
if (route.name === '/users/[id]') route.addAlias('/u/:id')
},
beforeWriteFiles(rootRoute) {
rootRoute.insert('/extra', new URL('./src/pages/extra.vue', import.meta.url).pathname)
},
})EditableTreeNode API: delete(), addAlias, meta getter/setter, addToMeta() (deep merge), insert(path, file), name (settable, false unsets since v5.3.0). Reflected in generated types.
Plugin options (dist/options-CwYZKRl4.d.mts:2635-2744)
| Option | Default | Purpose |
|---|---|---|
routesFolder |
'src/pages' |
string, { src, path, filePatterns, exclude, extensions }, or array; path prefixes route paths |
extensions |
['.vue'] |
page extensions; suffix stripping like .page.vue |
filePatterns |
['*/*'] |
picomatch globs relative to each folder |
exclude |
[] |
globs relative to cwd, e.g. ['src/pages/ignored/**'] |
importMode |
'async' |
`'sync' |
root |
process.cwd() |
base for all paths |
dts |
true |
true → typed-router.d.ts; string path; false to disable |
getRouteName |
file-path based | custom name generation (keep default for predictable names) |
routeBlockLang |
'json5' |
<route> block format |
watch |
!process.env.CI |
file watching |
logs |
false |
debug logs |
pathParser |
{ dotNesting: true } |
segment parsing options |
experimental.autoExportsDataLoaders |
— | (Vite only) globs of loader files re-exported by pages |
experimental.paramParsers |
— | enable custom resolvers/param matchers; true or { dir, include, exclude } |
Multiple route folders cannot contain one another.
Auto imports
import { VueRouterAutoImports } from 'vue-router/unplugin'
AutoImport({ imports: [VueRouterAutoImports] })Registers useRouter, useRoute, NavigationFailureType, isNavigationFailure, onBeforeRouteLeave, onBeforeRouteUpdate, definePage, loader helpers (dist/unplugin/index.d.mts:47-61).
ESLint
definePage is a macro: declare it globally (.eslintrc globals: { definePage: 'readonly' }) or import it where needed.