All skills
skilld-dev avatar

/vue-router-skilld

@b9c39cb

ALWAYS use when writing code that imports "vue-router", "vue-router/vite", "vue-router/auto-routes", or "vue-router/experimental". Consult for debugging, best practices, or modifying vue-router, vue router, router, file-based routing, typed routes, data loaders.

Use this Skill: https://skilld.dev/gh/skilld-dev/vue-ecosystem-skills/vue-router-skilld

This session only. Nothing lands on disk.

referencestyped-routes.md

≈1.3k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Typed routes and param parsers (vue-router@5.3.1)

How types wire up

The public generic types (RouteLocationRaw<Name>, useRoute(), push(), RouterLink to) all read RouteMap, which resolves from TypesConfig['RouteNamedMap'] if augmented, else falls back to a generic map (dist/options-CwYZKRl4.d.mts:88-92).

With file-based routing the generated typed-router.d.ts does the wiring for you:

// generated (excerpt): declares the map on vue-router/auto-routes,
// then points TypesConfig at it
declare module 'vue-router/auto-routes' {
  export interface RouteNamedMap { /* RouteRecordInfo per route */ }
}
declare module 'vue-router' {
  interface TypesConfig {
    RouteNamedMap: import('vue-router/auto-routes').RouteNamedMap
    _RouteFileInfoMap: import('vue-router/auto-routes')._RouteFileInfoMap
    _ParamParsers: { /* custom parser types */ }
  }
}

(dist/unplugin-C2XPnbvD.mjs:1661-1672)

Manual setup (no bundler plugin):

// typed-router.d.ts (hand written)
import type { RouteRecordInfo } from 'vue-router'
declare module 'vue-router/auto-routes' {
  export interface RouteNamedMap {
    '/users/[id]': RouteRecordInfo<'/users/[id]', '/users/:id', { id: string }, { id: string }>
  }
}
declare module 'vue-router' {
  interface TypesConfig { RouteNamedMap: import('vue-router/auto-routes').RouteNamedMap }
}

Augmenting TypesConfig on 'vue-router' (not 'vue-router/auto-routes' alone) is what activates the typed overloads.

What you get

router.push({ name: '/users/[id]', params: { id: '2' } }) // wrong name/param: type error
useRoute().params.id // typed per current page with the sfc-typed-router Volar plugin
route.fullPath        // exact literal union without Volar

Since v5.1.0 the Volar plugin also narrows typeof useRoute in type contexts and definePage's params.path keys are restricted to the file's actual path params via _RouteFileInfoMap (https://github.com/vuejs/router/releases/tag/v5.1.0, dist/index-D7ja2BKs.d.ts:1624-1679).

Param parsers (experimental)

Enable with experimental.paramParsers on the bundler plugin (true, or { dir, include, exclude }; defaults dir: ['src/params'], include: ['*.ts'], exclude: ['*.test.{ts,js}', '*.spec.{ts,js}'], flat folder only). Source: dist/options-CwYZKRl4.d.mts:2748-2769.

Native parsers: int → number, bool → boolean, string → string (dist/unplugin-C2XPnbvD.mjs:1078-1084).

Use in filenames: src/pages/users/[id=int].vue → route.params.id: number, match fails on non-integers.

Custom parser (file name becomes the parser name, camelCased; src/params/date.ts → date):

// src/params/date.ts
import { defineParamParser, miss } from 'vue-router/experimental'

export const parser = defineParamParser<Date>({
  get: value => {
    const date = new Date(value)
    if (Number.isNaN(date.getTime())) miss(`"${value}" is not a valid date`)
    return date
  },
  set: value => value.toISOString(),
})

defineParamParser handles optional (→ null) and repeatable (→ array) params for you (dist/experimental/index.js:737-772). miss() throws a MatchMiss internally so the route falls through to the next match (v5.0.3 made miss() return never, https://github.com/vuejs/router/releases/tag/v5.0.3).

defineParamParserRaw gives full control (you handle arrays/nullish yourself) (dist/experimental/index.js:691-736). Standard Schema validators (valibot, zod, ...) are accepted wherever a parser is expected since v5.0.5 (dist/index-D7ja2BKs.d.ts:1152-1167, https://github.com/vuejs/router/releases/tag/v5.0.5).

Query params via definePage:

definePage({
  params: {
    query: {
      page: { parser: 'int', default: 1 },        // ?page=3 → route.params.page === 3
      tags: { parser: 'string', format: 'array' }, // ?tags=a&tags=b → string[]
      token: { required: true },                   // route only matches if ?token present
    },
  },
})

Since v5, query params in typed routes are optional by default.

Experimental router + auto-resolver

experimental_createRouter replaces the routes array with a fixed resolver generated by the plugin. It has no addRoute/removeRoute (routes are build-time only) (dist/index-D7ja2BKs.d.ts:1578-1587).

import { experimental_createRouter } from 'vue-router/experimental'
import { createWebHistory } from 'vue-router'
import { resolver, handleHotUpdate } from 'vue-router/auto-resolver'

const router = experimental_createRouter({ history: createWebHistory(), resolver })
if (import.meta.hot) handleHotUpdate(router)

Requires experimental.paramParsers on the plugin so it emits the resolver module (vue-router-auto-resolver.d.mts:15-21). Types: EXPERIMENTAL_Router, EXPERIMENTAL_RouterOptions, records become EXPERIMENTAL_RouteRecord* with path/query/hash matcher patterns.

Global type overrides (TypesConfig)

Beyond RouteNamedMap, TypesConfig slots (marked internal but load-bearing, dist/options-CwYZKRl4.d.mts:8-23):

  • Router — swap the public Router type (v5.1.0 feature), also affects useRouter() return.
  • Error (on 'vue-router/experimental') — error type of data loaders (dist/index-D7ja2BKs.d.ts:1791-1809).
  • _ParamParsers, _RouteFileInfoMap — written by codegen; do not hand-edit unless you own the generation.

Source: SKILL.md on GitHub

No alerts9d3 checks · Risk SAFE
  • Gen Agent Trust Hub9d

    This skill is a technical documentation repository for Vue Router version 5.0.6. It provides detailed API references, migration guides from version 4, and best practices for implementing routing in Vue.js applications. No malicious code, obfuscation, or unauthorized access patterns were detected.

  • Socket9d

    No alerts

  • Snyk9d

    Risk: LOW · No issues

Signed by skilld at b9c39cb. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub last week.

Activeupdated last week

README badge

README badge for skilld-dev/vue-ecosystem-skills/vue-router-skilld