Skip to content

Introduction

Installation

Install using your favorite package manager:

bash
npm install -D unplugin-vue-router

Add the plugin to your bundler:

ts
import VueRouter from 'unplugin-vue-router/vite'

export default defineConfig({
  plugins: [
    VueRouter({
      /* options */
    }),
    // ⚠️ Vue must be placed after VueRouter()
    Vue(),
  ],
})
ts
import VueRouter from 'unplugin-vue-router/rollup'

export default {
  plugins: [
    VueRouter({
      /* options */
    }),
    // ⚠️ Vue must be placed after VueRouter()
    Vue(),
  ],
}
ts
module.exports = {
  /* ... */
  plugins: [
    require('unplugin-vue-router/webpack')({
      /* options */
    }),
  ],
}
ts
module.exports = {
  configureWebpack: {
    plugins: [
      require('unplugin-vue-router/webpack')({
        /* options */
      }),
    ],
  },
}
ts
import { build } from 'esbuild'
import VueRouter from 'unplugin-vue-router/esbuild'

build({
  plugins: [VueRouter()],
})

Setup

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:

json
{
  "include": [
    // other files...
    "./typed-router.d.ts"
  ],
  "compilerOptions": {
    // ...
    "moduleResolution": "Bundler",
    // ...
  }
}
ts
/* eslint-disable */
/* prettier-ignore */
// @ts-nocheck
// Generated by unplugin-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.

import type {
  RouteRecordInfo,
  ParamValue,
  ParamValueOneOrMore,
  ParamValueZeroOrMore,
  ParamValueZeroOrOne,
} from 'vue-router'

declare module 'vue-router/auto-routes' {
  /**
   * Route name map generated by unplugin-vue-router
   */
  export interface RouteNamedMap {
    '/': RouteRecordInfo<'/', '/', Record<never, never>, Record<never, never>>
    '/about': RouteRecordInfo<
      '/about',
      '/about',
      Record<never, never>,
      Record<never, never>
    >
    '/users/[id]': RouteRecordInfo<
      '/[id]',
      '/:id',
      { id: ParamValue<true> },
      { id: ParamValue<false> }
    >
  }
}

Then, if you have an env.d.ts file like the one created by npm vue create <my-project>, add the unplugin-vue-router/client types to it:

ts
/// <reference types="vite/client" />
/// <reference types="unplugin-vue-router/client" />

If you don't have an env.d.ts file, you can create one and add the unplugin-vue-router types to it or you can add them to the types property in your tsconfig.json:

json
{
  "compilerOptions": {
    // ...
    "types": [
      "unplugin-vue-router/client"
    ]
  }
}

WARNING

unplugin-vue-router will add a virtual vue-router/auto module that exports everything from vue-router with some extra features from unplugin-vue-router/runtime. It's recommended to avoid using vue-router/auto in new projects. It's kept for compatibility with existing projects that use it and will likely be removed in the future.

TIP

You can exclude vue-router/auto from VSCode import suggestions by adding this setting to your .vscode/settings.json:

json
{
  "typescript.tsdk": "node_modules/typescript/lib",
  "typescript.preferences.autoImportFileExcludePatterns": ["vue-router/auto$"]
}

This will ensure VSCode does not suggest vue-router/auto for imports. Alternatively, you can also configure auto imports.

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:

ts
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) 
} 
ts
import { createApp } from 'vue'
import { router } from './router'
import App from './App.vue'

createApp(App).use(router).mount('#app')
  • Rename src/pages/Home.vue to src/pages/index.vue
  • Rename src/pages/User.vue to src/pages/users/[id].vue
  • Rename src/pages/About.vue to src/pages/about.vue

Check the file-based routing guide for more information about the naming conventions.

From scratch

  • Create a src/pages folder and add an index.vue component to it. This will render your home page at /.
  • Import the routes from vue-router/auto-routes and pass them to the createRouter function.
ts
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')
vue
<template>
  <h1>Home</h1>
</template>

Check the file-based routing 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:

ts
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))
  }
)

Auto Imports

If you are using unplugin-auto-import, make sure to remove the vue-router preset and use the one exported by unplugin-vue-router:

ts
import { defineConfig } from 'vite'
import AutoImport from 'unplugin-auto-import/vite'
import { VueRouterAutoImports } from 'unplugin-vue-router'

export default defineConfig({
  plugins: [
    // other plugins
    AutoImport({
      imports: [
        'vue-router', 
        VueRouterAutoImports, 
      ],
    }),
  ],
})

If you use ESlint, check the ESlint section. If you use TypeScript or have a jsconfig.json file, check the TypeScript section.

Released under the MIT License.