Experimental Router Types
Vize recognizes the project-local typed-router opt-in used by Vue Router. Keep
the router's generated declarations and the opt-in in the same TypeScript project
for vize check, content mappers, and the Vize language server.
This recipe uses [email protected]. Experimental APIs can change between
versions. The upstream guide
can describe changes that are not in this published package.
Generate route declarations
Configure Vue Router's file scanner before the Vue compiler plugin:
// vite.config.ts
import { defineConfig } from "vite";
import VueRouter from "vue-router/vite";
import vize from "@vizejs/vite-plugin";
export default defineConfig({
plugins: [
VueRouter({
routesFolder: "src/pages",
dts: "typed-router.d.ts",
experimental: { paramParsers: { dir: "src/params" } },
}),
vize(),
],
});
Start Vite once to generate typed-router.d.ts. For CI that checks before
starting Vite, the same published scanner can generate it explicitly:
// scripts/generate-routes.mjs
import { createRoutesContext, resolveOptions } from "vue-router/unplugin";
const context = createRoutesContext(
resolveOptions({
root: process.cwd(),
routesFolder: "src/pages",
dts: "typed-router.d.ts",
experimental: { paramParsers: { dir: "src/params" } },
}),
);
try {
await context.scanPages(false);
context.writeConfigFiles();
} finally {
context.stopWatcher();
}
node scripts/generate-routes.mjs
Commit the generated declaration or generate it before checking. Regenerate it when page paths or parser declarations change. Vize consumes the real declaration; it does not replace the router's scanner.
Opt in per project
Add the following to the actual project containing your pages. Preserve other
compilerOptions, types, and plugins already in that project:
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "Bundler",
"strict": true,
"noEmit": true,
"skipLibCheck": true,
"rootDir": ".",
"types": ["vue-router/auto-routes"]
},
"vueCompilerOptions": {
"plugins": ["vue-router/volar/sfc-typed-router"]
},
"include": ["typed-router.d.ts", "src/**/*.ts", "src/**/*.vue"]
}
The plugin name enables Vize's built-in typed-router projection. It does not run arbitrary Volar plugins. Removing it disables that projection. A monorepo can enable it in one project without enabling another project.
This published-version recipe uses skipLibCheck: true for the router's
experimental declaration compatibility. Authored scripts and templates are still
checked.
Register the experimental router type
// src/router/index.ts
import { createWebHistory } from "vue-router";
import { experimental_createRouter as createRouter } from "vue-router/experimental";
import { resolver } from "vue-router/auto-resolver";
export const router = createRouter({ history: createWebHistory(), resolver });
declare module "vue-router" {
interface TypesConfig {
Router: typeof router;
}
}
Register RouterLink and RouterView from vue-router on your Vue app when using
the experimental router, as described in the upstream setup guide.
Use parsed values
Custom parser modules export parser. For example:
// 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();
return date;
},
set: (value) => value.toISOString(),
});
<!-- src/pages/products/[id=int].vue -->
<script setup lang="ts">
import { useRoute } from "vue-router";
import { definePage } from "vue-router/experimental";
definePage({
params: {
query: {
page: { parser: "int", format: "value", default: 1 },
at: { parser: "date", format: "value" },
},
},
});
const route = useRoute();
const id: number = route.params.id;
const page: number = route.params.page;
const at: Date | undefined = route.params.at;
</script>
<template>{{ id.toFixed() }} / {{ page.toFixed() }} / {{ at?.getFullYear() }}</template>
In published 5.4.0, import useRoute and useRouter from vue-router, and
definePage and parser helpers from vue-router/experimental.
Use the same selected project
vize check --tsconfig tsconfig.app.json
tsc --runExternalCode --noEmit -p tsconfig.app.json
The second command additionally needs the
content mapper configuration and a mapper-capable compiler.
Both commands must select the project that includes typed-router.d.ts and the
plugin opt-in above. For the language server, open the same project and enable
type checking with the recommended profile. If the project is not tsconfig.json,
set vue.typeChecker.tsconfig in your Vite settings to that same file; see
Configuration.
The VS Code and Art extensions use this language-server project configuration; there is no separate experimental-router setting in the extensions.
Published-version limits
The 5.4.0 package does not export _RoutePropsForFilePath and does not provide the
new automatic props: true augmentation of defineProps(). Do not copy an
unpublished helper declaration into your project to enable it. Newer upstream
contracts require their own provider version and compatibility validation.
Support for experimental route types in additional script and template languages is being qualified separately. The setup above covers Vue SFCs with TypeScript scripts and HTML templates; it does not promise parity for every preprocessor.