vuejs/router vue-router
Version: 5.0.4
Deps: @babel/generator@^7.28.6, @vue-macros/common@^3.1.1, @vue/devtools-api@^8.0.6, ast-walker-scope@^0.8.3, chokidar@^5.0.0, json5@^2.2.3, local-pkg@^1.1.2, magic-string@^0.30.21, mlly@^1.8.0, muggle-string@^0.4.1, pathe@^2.0.3, picomatch@^4.0.3, scule@^1.3.0, tinyglobby@^0.2.15, unplugin@^3.0.0, unplugin-utils@^0.3.1, yaml@^2.8.2
Tags: next: 4.0.13, legacy: 3.6.5, edge: 4.4.0-alpha.3, beta: 5.0.0-beta.2, latest: 5.0.4
References: Docs — API reference, guides • GitHub Issues — bugs, workarounds, edge cases • GitHub Discussions — Q&A, patterns, recipes • Releases — changelog, breaking changes, new APIs
API Changes
This section documents version-specific API changes — prioritize recent major/minor releases.
NEW: vue-router/vite — v5 ships the Vite plugin (formerly unplugin-vue-router/vite) directly in the core package; import from vue-router/vite instead source
NEW: vue-router/auto-routes — v5 export that provides the auto-generated file-based route list; previously required unplugin-vue-router as a separate package source
NEW: vue-router/unplugin — v5 export for Webpack/Rollup/esbuild plugins and utilities (VueRouterAutoImports, EditableTreeNode, createRoutesContext, etc.); previously imported from unplugin-vue-router source
NEW: DataLoaderPlugin + defineBasicLoader (experimental) — v5 adds data loaders directly to vue-router/experimental; previously in unplugin-vue-router/data-loaders. Install DataLoaderPlugin before the router with app.use(DataLoaderPlugin, { router }) source
NEW: defineColadaLoader (experimental) — Pinia Colada-backed loader available at vue-router/experimental/pinia-colada; previously unplugin-vue-router/data-loaders/pinia-colada source
NEW: NavigationResult (experimental) — class from vue-router/experimental returned inside a loader to redirect during navigation (e.g. return new NavigationResult('/login')); previously did not exist in vue-router source
NEW: Volar plugins moved to vue-router/volar/sfc-typed-router and vue-router/volar/sfc-route-blocks — previously unplugin-vue-router/volar/sfc-typed-router and unplugin-vue-router/volar/sfc-route-blocks source
NEW: TypesConfig module augmentation — v4.4+ interface used to register RouteNamedMap for typed routes; augment with declare module 'vue-router' { interface TypesConfig { RouteNamedMap: RouteNamedMap } } source
BREAKING: IIFE build no longer bundles @vue/devtools-api — v5 upgraded devtools-api to v8 which has no IIFE build; affects CDN/script-tag setups that relied on the bundled devtools source
NEW: Query params optional by default (experimental) — v5 file-based routing makes query params optional in typed routes by default source
Also changed: unplugin-vue-router types/utilities moved to vue-router/unplugin (renamed) · route-map.d.ts replaces typed-router.d.ts (renamed) · meta.loaders array on route records for manually connecting data loaders (NEW, experimental) · router.currentRoute is Ref<RouteLocationNormalizedLoaded> — access via .value (v4 BREAKING) · router.onReady() removed — use router.isReady() returning a Promise (v4 BREAKING) · scrollBehavior x/y renamed to left/top (v4 BREAKING)
Best Practices
Use route.meta directly in guards instead of iterating to.matched — Vue Router merges all ancestor meta fields non-recursively, so to.meta.requiresAuth already reflects inherited values from parent routes source
Extend the RouteMeta interface via module augmentation to type all meta fields — this enforces that every route declares required fields at compile time rather than relying on runtime checks source
Use router.beforeResolve (not beforeEach) for operations that must run after async components are resolved — it fires after all in-component guards and async route components are ready, making it the correct place for camera permission checks or final data validation source
Use inject() inside navigation guards (global or per-route) to access Pinia stores and provided values — this is supported since Vue 3.3 and avoids importing stores outside of setup context source
Avoid the next callback in guards — return values (false, a route location, or nothing) instead; next is error-prone because it must be called exactly once per code path and is considered a legacy API source
await router.push() and check the resolved value to detect navigation failures — the promise resolves to a NavigationFailure when blocked, or undefined on success; use isNavigationFailure(result, NavigationFailureType.aborted) to distinguish the specific failure type source
Set props: true (or a function) on route records to decouple components from useRoute() — components receiving params as props are reusable and testable without a router instance; use the function form (props: route => ({ query: route.query.q })) to map query params or cast types source
Watch specific route properties rather than the whole route object — useRoute() returns a reactive object, but watching it entirely triggers on any change (hash, query, params); narrow the watcher to () => route.params.id to avoid unnecessary fetches source
(experimental) Use defineBasicLoader / defineColadaLoader exported from page components for navigation-aware data fetching — loaders exported from lazy-loaded route components are automatically connected to the navigation lifecycle, block the transition until resolved, and expose isLoading/error reactively; set lazy: true for non-critical data that should not block navigation source
Converted and distributed by TomeVault — claim your Tome and manage your conversions.
1---2name: vue-router-skilld-33description: ALWAYS use when writing code importing \"vue-router\". Consult for debugging, best practices, or modifying vue-router, vue router, router. Use when this capability is needed.4---56# vuejs/router `vue-router`78**Version:** 5.0.49**Deps:** @babel/generator@^7.28.6, @vue-macros/common@^3.1.1, @vue/devtools-api@^8.0.6, ast-walker-scope@^0.8.3, chokidar@^5.0.0, json5@^2.2.3, local-pkg@^1.1.2, magic-string@^0.30.21, mlly@^1.8.0, muggle-string@^0.4.1, pathe@^2.0.3, picomatch@^4.0.3, scule@^1.3.0, tinyglobby@^0.2.15, unplugin@^3.0.0, unplugin-utils@^0.3.1, yaml@^2.8.210**Tags:** next: 4.0.13, legacy: 3.6.5, edge: 4.4.0-alpha.3, beta: 5.0.0-beta.2, latest: 5.0.41112**References:** [Docs](./references/docs/_INDEX.md) — API reference, guides • [GitHub Issues](./references/issues/_INDEX.md) — bugs, workarounds, edge cases • [GitHub Discussions](./references/discussions/_INDEX.md) — Q&A, patterns, recipes • [Releases](./references/releases/_INDEX.md) — changelog, breaking changes, new APIs13## API Changes1415This section documents version-specific API changes — prioritize recent major/minor releases.1617- NEW: `vue-router/vite` — v5 ships the Vite plugin (formerly `unplugin-vue-router/vite`) directly in the core package; import from `vue-router/vite` instead [source](./references/docs/guide/migration/v4-to-v5.md#2-update-imports)1819- NEW: `vue-router/auto-routes` — v5 export that provides the auto-generated file-based route list; previously required `unplugin-vue-router` as a separate package [source](./references/docs/guide/migration/v4-to-v5.md#new-exports-reference)2021- NEW: `vue-router/unplugin` — v5 export for Webpack/Rollup/esbuild plugins and utilities (`VueRouterAutoImports`, `EditableTreeNode`, `createRoutesContext`, etc.); previously imported from `unplugin-vue-router` [source](./references/docs/guide/migration/v4-to-v5.md#2-update-imports)2223- NEW: `DataLoaderPlugin` + `defineBasicLoader` (experimental) — v5 adds data loaders directly to `vue-router/experimental`; previously in `unplugin-vue-router/data-loaders`. Install `DataLoaderPlugin` **before** the router with `app.use(DataLoaderPlugin, { router })` [source](./references/releases/v5.0.0.md#features)2425- NEW: `defineColadaLoader` (experimental) — Pinia Colada-backed loader available at `vue-router/experimental/pinia-colada`; previously `unplugin-vue-router/data-loaders/pinia-colada` [source](./references/docs/guide/migration/v4-to-v5.md#2-update-imports)2627- NEW: `NavigationResult` (experimental) — class from `vue-router/experimental` returned inside a loader to redirect during navigation (e.g. `return new NavigationResult('/login')`); previously did not exist in vue-router [source](./references/docs/data-loaders/defining-loaders.md#navigation-control)2829- NEW: Volar plugins moved to `vue-router/volar/sfc-typed-router` and `vue-router/volar/sfc-route-blocks` — previously `unplugin-vue-router/volar/sfc-typed-router` and `unplugin-vue-router/volar/sfc-route-blocks` [source](./references/docs/guide/migration/v4-to-v5.md#2-update-imports)3031- NEW: `TypesConfig` module augmentation — v4.4+ interface used to register `RouteNamedMap` for typed routes; augment with `declare module 'vue-router' { interface TypesConfig { RouteNamedMap: RouteNamedMap } }` [source](./references/docs/guide/advanced/typed-routes.md#manual-configuration)3233- BREAKING: IIFE build no longer bundles `@vue/devtools-api` — v5 upgraded devtools-api to v8 which has no IIFE build; affects CDN/script-tag setups that relied on the bundled devtools [source](./references/releases/v5.0.0.md#v500)3435- NEW: Query params optional by default (experimental) — v5 file-based routing makes query params optional in typed routes by default [source](./references/releases/v5.0.0.md#features)3637**Also changed:** `unplugin-vue-router` types/utilities moved to `vue-router/unplugin` (renamed) · `route-map.d.ts` replaces `typed-router.d.ts` (renamed) · `meta.loaders` array on route records for manually connecting data loaders (NEW, experimental) · `router.currentRoute` is `Ref<RouteLocationNormalizedLoaded>` — access via `.value` (v4 BREAKING) · `router.onReady()` removed — use `router.isReady()` returning a Promise (v4 BREAKING) · `scrollBehavior` `x`/`y` renamed to `left`/`top` (v4 BREAKING)3839## Best Practices4041- Use `route.meta` directly in guards instead of iterating `to.matched` — Vue Router merges all ancestor `meta` fields non-recursively, so `to.meta.requiresAuth` already reflects inherited values from parent routes [source](./references/docs/guide/advanced/meta.md#typescript)4243- Extend the `RouteMeta` interface via module augmentation to type all `meta` fields — this enforces that every route declares required fields at compile time rather than relying on runtime checks [source](./references/docs/guide/advanced/meta.md#typescript)4445- Use `router.beforeResolve` (not `beforeEach`) for operations that must run after async components are resolved — it fires after all in-component guards and async route components are ready, making it the correct place for camera permission checks or final data validation [source](./references/docs/guide/advanced/navigation-guards.md#global-resolve-guards)4647- Use `inject()` inside navigation guards (global or per-route) to access Pinia stores and provided values — this is supported since Vue 3.3 and avoids importing stores outside of `setup` context [source](./references/docs/guide/advanced/navigation-guards.md#global-injections-within-guards)4849- Avoid the `next` callback in guards — return values (`false`, a route location, or nothing) instead; `next` is error-prone because it must be called exactly once per code path and is considered a legacy API [source](./references/docs/guide/advanced/navigation-guards.md#optional-third-argument-next)5051- `await router.push()` and check the resolved value to detect navigation failures — the promise resolves to a `NavigationFailure` when blocked, or `undefined` on success; use `isNavigationFailure(result, NavigationFailureType.aborted)` to distinguish the specific failure type [source](./references/docs/guide/advanced/navigation-failures.md#detecting-navigation-failures)5253- Set `props: true` (or a function) on route records to decouple components from `useRoute()` — components receiving params as props are reusable and testable without a router instance; use the function form (`props: route => ({ query: route.query.q })`) to map query params or cast types [source](./references/docs/guide/essentials/passing-props.md#function-mode)5455- Watch specific `route` properties rather than the whole `route` object — `useRoute()` returns a reactive object, but watching it entirely triggers on any change (hash, query, params); narrow the watcher to `() => route.params.id` to avoid unnecessary fetches [source](./references/docs/guide/advanced/composition-api.md#accessing-the-router-and-current-route-inside-setup)5657- (experimental) Use `defineBasicLoader` / `defineColadaLoader` exported from page components for navigation-aware data fetching — loaders exported from lazy-loaded route components are automatically connected to the navigation lifecycle, block the transition until resolved, and expose `isLoading`/`error` reactively; set `lazy: true` for non-critical data that should not block navigation [source](./references/docs/data-loaders/defining-loaders.md#non-blocking-loaders-with-lazy)5859---60> Converted and distributed by [TomeVault](https://tomevault.io/claim/harlan-zw) — claim your Tome and manage your conversions.61<!-- tomevault:4.0:skill_md:2026-04-16 -->