🚦 The official router for Vue.js.

Last update: Jun 29, 2022

vue-router Build Status

This is vue-router 3.0 which works only with Vue 2.0. For the 1.x router see the 1.0 branch.

Supporting Vue Router

Vue Router is part of the Vue Ecosystem and is an MIT-licensed open source project with its ongoing development made possible entirely by the support of Sponsors. If you would like to become a sponsor, please consider:

Silver Sponsors

Vue Mastery Vuetify

Bronze Sponsors

Storyblok Storyblok

Get started with the documentation, or play with the examples (see how to run them below).

Development Setup

# install deps
npm install

# build dist files
npm run build

# serve examples at localhost:8080
npm run dev

# lint & run all tests
npm test

# serve docs at localhost:8080
npm run docs


  • yarn run release
    • Ensure tests are passing yarn run test
    • Build dist files VERSION=<the_version> yarn run build
    • Build changelog yarn run changelog
    • Commit dist files git add dist CHANGELOG.md && git commit -m "[build $VERSION]"
    • Publish a new version `npm version $VERSION --message "[release] $VERSION"
    • Push tags git push origin refs/tags/v$VERSION && git push
    • Publish to npm npm publish


For questions and support please use the Discord chat server or the official forum. The issue list of this repo is exclusively for bug reports and feature requests.


Please make sure to read the Issue Reporting Checklist before opening an issue. Issues not conforming to the guidelines may be closed immediately.


Please make sure to read the Contributing Guide before making a pull request.


Details changes for each release are documented in the CHANGELOG.md file.

Stay In Touch

  • For latest releases and announcements, follow on Twitter: @vuejs



Copyright (c) 2013-present Evan You

Special Thanks

BrowserStack Logo

Special thanks to BrowserStack for letting the maintainers use their service to debug browser specific issues.


  • 1. Allow absolute path change without destroying rendered components (Twitter-style modals)

    Status Quo

    In vue-router, the URL is the single source of truth. That means that no matter weither the user triggers a route from an external link, by typing out the URL himself or by clicking on a <router-link> inside our app, the same route if the URL is the same, then the same routes will be matched, and the same components will be rendered - no side-effects are taken into account.

    I consider this to be a sensible, good approach. But there are situations where this behaviour is undesired:

    The problem

    If you go to Twitter's website, and open a tweet from any place (your own timeline, someone else's timeline, a list ...), three things happen:

    1. A modal with the tweet opens
    2. the URL changes to an absolute URL pointing to that tweet
    3. Something doesn't change, though: the background of the modal. Even though we started from e.g. twitter.com/linus_borg and went to twitter.com/vuejs/status/xxxxx when we opened the modal, my profile's timeline is still in the brackground.

    The user could simply copy & paste the tweets URL, post it somewhere, go back to twitter, close the modal and continue browsing my profile. Great!

    Butr currently, this is not possible with vue-router. With vue-router, we would either have to

    • render the modal as a child-route of my timeline, which means the URL would not point to the tweet really, but to /linus_borg_/status/vuejs/status/... or something.
    • render the tweet route as an absolute path, but then the background view (my profile) would be destroyed.


    This breaks vue-routers philsophy of the URL as the only source of truth, because opening a tweet from timeline leads to a different view than opening the tweet's URL directly.

    Proposed Solution(s)

    Here this proposal becomes thin, and I didn't add the discussion label for nothing:

    I don't really have an idea on how to approach this. I know that it's probably very hard to implement this in vue-router as it working different to the whole route-matching pattern etc, so I'm open to ideas.

    Maybe, we could at least implement a way to "pause" the router's URL change callback? So the user can "deactivate" the router momentarily, change the URL himself, show the modal, and on closing the modal, reactivate the router?

    Or maybe this could be accomplished with named router views, if we allow route that only point to a named view , so the "normal components, e.g. the profile, stay rendered, and we show the overlay in a named view? (tested this, doesn't work right now).

    Anyways, I think this wold be a great feature for many scenarios (Spotify's uses this for its ovelays showing album / playlist / artist views anywhere, for example)

    So, what do you guys think? Any opinions? Ideas for solutions?

    Reviewed by LinusBorg at 2016-09-30 13:37
  • 2. 关于html5-History模式在微信浏览器内的问题


    在hash模式下,wx.config()可以正常工作,但在history模式下,安卓手机中无法正常config,会提示invalid signature的错误,IOS下则是正常的,非常困扰。查了微信的文档说安卓手机可能是pushState引起的。

    @everyone give me some help...

    Reviewed by lmnsg at 2016-04-27 09:46
  • 3. [Feature] A reload method like location.reload()

    I have a router-view that needs to be reloaded after sending some POST requests and receiving whether the operation was successful, but


    doesn't trigger a reload even if the component's route.canReuse is set to false.

    Now I can only do

    created.apply(this) // `created` is the life-cycle hook function for the component

    in the ajax callback to force the router-view to update itself, which is cumbersome.

    Perhaps something like $route.router.reload() would be great, as it would be the counterpart of location.reload().

    Reviewed by fnlctrl at 2015-12-18 03:59
  • 4. Dynamically add child routes to an existing route

    I am building a large scale application with "mini applications" hosted within the application. Each mini application is being developed by another team. I would like to dynamically add nested child routes to an existing route to allow dynamic registration of each of the mini apps.

    for example:

    const routes = [
            {path: 'a', component: ComponentA, name: 'a'},
            {path: 'b', component: ComponentB, name: 'b'},
    export default Vue.extend({
        beforeCreate () {
            this.$router.addChildRoutes(this.$router.currentRoute.path, routes);
        template: `
      <div class="page-host">
      <router-link to="{name: 'a'}">a</router-link>
      <router-link to="{name: 'b'}">b</router-link>
      <transition name="fade" mode="out-in">
        <keep-alive><router-view class="view"></router-view></keep-alive>
    //The app itself
    import MiniApp from "./MiniApp";
    const config = {
        linkActiveClass: 'active',
        scrollBehavior: () => ({x: 0, y: 0}),
        routes: [
            {path: '/mini', component: MiniApp, name: 'mini'}},
    let router = new Router(config);
    const vue = new Vue({
       template: `
      <div class="page-host">
      <router-link to="/mini">a</router-link>
      <transition name="fade" mode="out-in">
        <keep-alive><router-view class="view"></router-view></keep-alive>
    Reviewed by miki2826 at 2017-02-11 11:10
  • 5. Allow components to define their routes in their definition file instead of having them all in one place

    Since components are already taking care of not polluting other places, I believe it would be really nice to have components declare their own routes (subroutes actually) in their own space. This would really help for huge apps and it would favor components reusability. I was thinking of a 'routes' object in the component's definition object but this could be in a vue file as well.

    Reviewed by booss at 2015-12-19 15:23
  • 6. Failed to mount component: template or render function not defined. (found in root instance)

    I write it in this case, but it is wrong. http://router.vuejs.org/en/essentials/getting-started.html

    "vue": "^2.0.1",
    "vue-router": "^2.0.0",
    "vuex": "^2.0.0"
    <!DOCTYPE html>
    <html lang="en">
        <meta charset="UTF-8">
    <div id="app">
      <h1>Hello App!</h1>
        <!-- use router-link component for navigation. -->
        <!-- specify the link by passing the `to` prop. -->
        <!-- <router-link> will be rendered as an `<a>` tag by default -->
        <router-link to="/foo">Go to Foo</router-link>
        <router-link to="/bar">Go to Bar</router-link>
      <!-- route outlet -->
      <!-- component matched by the route will render here -->
    import Vue from 'vue'
    import VueRouter from 'vue-router'
    // 0. If using a module system, call Vue.use(VueRouter)
    // 1. Define route components.
    // These can be imported from other files
    const Foo = { template: '<div>foo</div>' }
    const Bar = { template: '<div>bar</div>' }
    // 2. Define some routes
    // Each route should map to a component. The "component" can
    // either be an actual component constructor created via
    // Vue.extend(), or just a component options object.
    // We'll talk about nested routes later.
    const routes = [
      { path: '/foo', component: Foo },
      { path: '/bar', component: Bar }
    // 3. Create the router instance and pass the `routes` option
    // You can pass in additional options here, but let's
    // keep it simple for now.
    const router = new VueRouter({
      routes // short for routes: routes
    // 4. Create and mount the root instance.
    // Make sure to inject the router with the router option to make the
    // whole app router-aware.
    const app = new Vue({
    // Now the app has started!
    open url http://localhost:3000/admin/#/bar
    Reviewed by lzxb at 2016-10-02 10:48
  • 7. No stacktrace on NavigationDuplicated error uncaught in promise



    Reproduction link


    Steps to reproduce

    1. Call $router.replace or $router.push twice with same path

    What is expected?

    Error object provides stacktrace (stack property)

    What is actually happening?

    No stack trace in the error object

    When NavigationDuplicated error is thrown, there is no stack trace in the error itself so when error is reported through error reporting service like Sentry, there is absolutely no context to go with the error and so it's hard to figure out where that error originated.

    Transpiled code for the NavigationDuplicated class looks like this: https://github.com/vuejs/vue-router/blob/5141def3a21da479c2858c0d70db3cb438c3b7d0/dist/vue-router.common.js#L1935-L1946

    which is problematic because instantiating such function won't create a stacktrace. It would work fine with non-transpiled code (although I'm not suggesting to not transpile it): https://github.com/vuejs/vue-router/blob/44c63a963f05ede229d8658a45b2388e244ce00b/src/history/errors.js#L1

    One possible solution would be to manually set stack trace with:

    this.stack = (new Error()).stack;

    but I'm not sure how that would be done if transpilation is done by webpack/babel...

    There is also one extra bug in that code. The line that instantiates error passes a route object to the error: https://github.com/vuejs/vue-router/blob/fc42d9cf8e1d381b885c9af37003198dce6f1161/src/history/base.js#L125 but error doesn't do anything with it: https://github.com/vuejs/vue-router/blob/44c63a963f05ede229d8658a45b2388e244ce00b/src/history/errors.js#L2

    Saving route properties on the error object would also help in deciphering source of the error.

    Reviewed by rchl at 2019-08-08 19:36
  • 8. Allow nested routes' components to be mounted at root-level

    What problem does this feature solve?

    I'm developing a Quasar app where I have, for example, the following route structure:

    const router = new VueRouter({
      routes: [
          path: '/clients',
          component: Clients,
          children: [
              path: ':id',
              component: Client,
              children: [
                  path: 'visits',
                  component: ClientVisits

    In all three routes I have a beforeRouteEnter guard that fetches data from an API and stores that data in a Vuex instance. Furthermore, ClientVisits uses the data that was fetched and stored in Client.

    In terms of UI design, though, I do not want ClientVisits to be shown as a nested child view; it needs to be at the top level. If you know Android development, ClientVisits should work as an Activity and not a Fragment.

    What does the proposed API look like?

    Perhaps if Client had no <router-view> in its template, children would then be mounted at root level?

    Reviewed by rhyek at 2017-06-13 18:20
  • 9. Cannot prevent router-link event

    It looks like the click event on the <router-link> is handled before any custom click events:

    <router-link to="/b" @click.native.prevent="clicked">should NOT route to b</router-link>
    const app = new Vue({
      methods: {
      	clicked: function(e) {
            // Does not prevent route change

    See working fiddle: https://jsfiddle.net/floorish/zhyqgqpz/ The <router-link> component checks e.defaultPrevented here : https://github.com/vuejs/vue-router/blob/dev/src/components/link.js#L49 , but that is still false when it checks the condition.

    Only workaround I've found is to capture the event on a parent element (included in fiddle).

    Vue version: 2.0.7 Vue-router version: 2.0.2 Possibly related to: https://github.com/vuejs/vue-router/issues/390

    Reviewed by floorish at 2016-11-18 11:43
  • 10. Feature request: enable some way of handling external links by router.

    I have read a number of discussions on this and think it's worthwhile to raise this as an enhancement.

    The following esults in each element rendering as an <li> with appropriate list styling but acting like a link. The problem is that if one of the links is to an external site it fails.

      <nav class="navs">
        <ul class="nav">
          <!-- -->
            class="nav__item nav__link"
            v-for="nav in navs">
            {{ nav.name }}

    It's possible to convolute the logic with something like the following. It requires directly inserting the <a> elements but works given minor changes to CSS or always inserting links inside <li> elements (even though if there are no external links it can be coded using <router-link tag="li" ...>).

      <li v-for="nav in navs">
        <a v-if="nav.external" class="nav__item nav__link" :href="nav.link">{{ nav.name }}</a>
        <router-link v-else
          class="nav__item nav__link"
        >{{ nav.name }}</router-link>

    I previously tried just inserting external URLs into the <router-link> elements and handling them in router.beforeEach(). It's possible to apply some heuristic checks to see if the URL is external and set window.location.href if it is. But the problem I ran into then is that using the browser back button always resulted in an error because the history is stored as localhost:8080/http:/google.com (when testing with "http://google.com" as the external link).

    It seems that that programmatically building lists of links is a common problem and that there should be a straightforward solution. Two solutions that would help me are 1) allowing the "external" prop on <router-link> elements that correctly stores history so the back button works or 2) provide some way in router.beforeEach() to prevent storing the unusable history entry. I think the first, or some variation where the externality of a link specified in the element, is the most straightforward.

    I guess another solution is a strong recommendation in documentation on how to handle this seemingly common situation.

    Thanks for considering it.

    Reviewed by bmacnaughton at 2017-03-26 04:01
  • 11. Multiple guards support

    There is any plan to add multiple guards support for Per-Route Guards?

    For the cases where have multiple resolves before access to the route. for example check if user connected, next check if user is active, next check if resource is available... All before go into route.

    maybe passing an array of functions to beforeEach and going to the view after the last next. something like

        path: '/hello', 
        component: Hello, 
        beforeEach: [function(from, to, next){
          // first check
          // ...
          next() // goes to seccond check
        }, function(from, to, next){
          // seccond check
          // ...
          next() // If last check -> goes to component Hello

    Would be great

    Reviewed by sonic182 at 2016-10-04 12:04
  • 12. [Feature Request] Add support for Vue 2.7

    What problem does this feature solve?

    As composition api has been incoporated in vue 2.7, vue-router should provide useRoute and useRouter to enable router usage in <setup script>.

    What does the proposed API look like?

    const router = useRouter()

    Just like in Vue3

    Reviewed by kingyue737 at 2022-06-20 08:12
  • 13. Matcher is linear and uses too many regex

    What problem does this feature solve?

    The matcher implementation always use path-to-regex lib. It is too much for static paths, where it is possible to just compare strings.

    Also, the implementatioin is O(N), if you have 100 routes and want to match the last one (that is static), you run 100 regex tests. Regex is around ~10x slower than a simple string match and with a lookup table it is O(1).


    What does the proposed API look like?

    The API don't change, it is just optimization.

    I did a draft PR #3707 to show the idea.

    Reviewed by iurisilvio at 2022-01-30 09:44
  • 14. WIP: Optimized matcher

    This is a draft implementation with some new ideas.

    • Static paths don't need regex match for most cases.
    • Match don't have to be always linear, it is possible to match only with static paths.

    Regex match is 10x slower than simple object access. I still have to run some dynamic matches to not break ordering compatibility.

    I still want to integrate it better with current code, I did this implementation to validate the issue and run some benchmarks.

    Reviewed by iurisilvio at 2022-01-30 04:01
Elegant, fluent route definitions for Vue Router, inspired by Laravel. v3 is currently in beta. [email protected]

Elegant, fluent route definitions for Vue Router, inspired by Laravel. Routisan 3 is currently in beta. Stable release around the corner! npm i vue-ro

Jun 7, 2022
🚦This is the repository for Vue Router 4 (for Vue 3)
🚦This is the repository for Vue Router 4 (for Vue 3)

vue-router This is the repository for Vue Router 4 (for Vue 3) Supporting Vue Router Vue Router is part of the Vue Ecosystem and is an MIT-licensed op

Jun 29, 2022
Generate sitemap.xml by vue-router configuration

vue-router-sitemap Generate sitemap.xml by vue-router configuration Install npm i --save vue-router-sitemap Example usage // router.js import VueRout

May 31, 2022
A Trie-based vue router with the ability of managing history.state.

vue-pilot A Trie-based vue router with the ability of managing history.state. Install npm install vue-pilot Features Small (8kb after gzipped). Abili

Nov 16, 2020
Vue Router route config generator

vue-route-generator Vue Router route config generator. You may want to use vue-auto-routing for auto generating routing or vue-cli-plugin-auto-routing

May 27, 2022

hello-vue-router Project setup npm install Compiles and hot-reloads for development npm run serve Compiles and minifies for production npm run build

Dec 23, 2021
Touring Vue Router Example App

Touring Vue Router Example App This is the Vue 3 application we build step by step in the Touring Vue Router course on Vue Mastery. It's starting code

Dec 30, 2021
Vue Router route config generator

vue-route-generator Vue Router route config generator. You may want to use vue-auto-routing for auto generating routing or vue-cli-plugin-auto-routing

Jul 3, 2021
A tool to generate routes for Vue-Router with Vite.

v-route-generate A tool to generate routes for Vue-Router with Vite. Getting Started Install v-route-generate # Choose a package manager you like. #

May 21, 2022
Generate Vue Router routes automatically using a markdown arborescence.

Generate Vue Router routes automatically using a markdown arborescence.

May 19, 2020
Automated generation of vue-router

自动生成router文件 通常情况下一个vue项目,随着时间的增加,router会越来越多,而大部分的代码其实都是重复的,修改很麻烦,还不如通过工具生成。

Oct 13, 2021
Lightweight layout resolver for Vue Router

vue-router-layout Lightweight layout resolver for Vue Router. You may want to use vue-cli-plugin-auto-routing which includes all useful features on ro

May 10, 2022
Filesystem based route generation for Webpack + vue-router

@badrap/routdir Filesystem based route generation for Webpack + vue-router. @badrap/routdir is based on Sapper's pages and layouts features, with some

Jan 25, 2021
VRouteHelper - package to add that kind of syntax for vue-router.

VRouteHelper I really like how easy it is to specify routes in Laravel so I made this package to add that kind of syntax for vue-router. Any feedback

Apr 25, 2019
Generate Vue Router routing automatically for multipages

Generate Vue Router routing automatically for multipages

Dec 8, 2018
Provides a wrapper for router-view that allows you to show error pages without changing the URL.

vue-error-page Provides a wrapper for router-view that allows you to show error pages without changing the URL. Why? Because: Trigger router-view chan

Apr 6, 2022
Smart route search to make intelligent looking apps with Vue.js.
Smart route search to make intelligent looking apps with Vue.js.

Make your users dynamically navigate routes, make smart commands and queries with a single directive. Vue Smart Route allows you to create a query sys

Jun 19, 2022
Vue language routing with (optional) localized URLs.
Vue language routing with (optional) localized URLs.

?? Vue Language Router Language routing and URL localization made easy. Built on top of ?? Vue Router and ?? Vue I18n. Demo You can play with demo at

Apr 14, 2022
Event-based routing system for Vue.js.
Event-based routing system for Vue.js.

Vue Lanes Event-based routing system for Vue.js. Example Vue Lanes need to be initialized first. The Lanes extended Vue will let you create Vue Lanes

Feb 18, 2022