Advanced Routing with Vue and Vue Router: Redirects & Nav Guards

Jim Toth

While the basics of routing in Vue.js have already been covered, today we’ll explore some other features Vue Router has to offer such as redirects and navigation guards.

Other advanced Vue Router topics already covered by Alligator.io include Route Meta Fields and Nested Routes so make sure to check those out. With that said, let’s get started!

Setup

Since this is about advanced routing features offered by Vue Router, you probably already know how to accomplish a basic setup. Just in case, here’s a bare-bones setup:

# Yarn
$ yarn add vue-router
# NPM
$ npm install vue-router --save

main.js

import Vue from 'vue';
import VueRouter from 'vue-router';

Vue.use(VueRouter);

const Swamp = { template: '<div>Swamp</div>' };
const Gator = { template: '<div>Gator</div>' };

const router = new VueRouter({
  routes: [
    { path: '/swamp', component: Swamp },
    { path: '/gator', component: Gator }
  ]
});

const app = new Vue({
  router
}).$mount('#app');

Redirects

There are a few ways we can accomplish redirects with Vue Router. Redirects will change the route to the intended target and reflect this change in the current URL.

const router = new VueRouter({
  routes: [
    { path: '/swamp', component: Swamp },
    { path: '/gator', component: Gator },
    { path: '/croc', redirect: '/gator' }
  ]
});

When a user navigates to /croc, instead they’ll be redirected to /gator and the URL in the address bar will be /gator.

We can also use a function to accomplish dynamic routing:

const router = new VueRouter({
  routes: [
    { path: '/swamp', component: Swamp },
    { path: '/gator', component: Gator },
    { path: '/croc', redirect: to => {
  return '/gator';
}}
  ]
});

In the above code, the argument to contains the original target route object with information such as the route’s path or name.

Aliases

Aliases are like redirects but do not update the URL when the route is matched.

const router = new VueRouter({
  routes: [
    { path: '/swamp', component: Swamp, alias: '/bayou' },
    { path: '/gator', component: Gator },
    { path: '/croc', redirect: to => {
      return '/gator';
    }}
  ]
});

With the above configuration, a user navigating to /swamp will get the Swamp component with a url of /swamp. If a user instead navigates to /bayou, they’ll still get the Swamp component but the url will remain /bayou.

Now that we’ve covered Redirects, let’s cover a related but more complex topic: Navigation Guards. Navigation Guards allow us to dynamically prevent navigation in vue-router via redirects or cancellation. If a user of our app doesn’t have permissions to view /admin, we can either cancel or redirect the user to an appropriate alternate route. This is important so users aren’t exposed to components that aren’t relevant to their interests.

As a basic example, we can use a simple Navigation Guard to redirect a user to a login page if they are not yet authenticated:


  const router = new VueRouter({
  routes: [
    { path: '/swamp', component: Swamp, alias: '/bayou' },
    { path: '/gator', component: Gator },
    { path: '/croc', redirect: to => {
      return '/gator';
    }},
    { path: '/login', name: 'login', component: Login }
  ]
});

router.beforeEach((to, from, next) => {
  if (to.name !== 'login' && !isAuthenticated) {
    next({ name: 'login' });
  } else {
    next();
  }
});

We can also define guards on a per-route basis:


  const router = new VueRouter({
  routes: [
    { path: '/swamp', component: Swamp, alias: '/bayou' },
    {
  path: '/gator',
  component: Gator,
  beforeEnter: (to, from, next) => {
    console.log(`${from.path} to ${to.path}?`);
    next();
  }
},
    { path: '/croc', redirect: to => {
      return '/gator';
    }},
    { path: '/login', name: 'login', component: Login }
  ]
});

Make sure to only ever call next() one time or you could run into errors or incorrect path resolution!

Components themselves can also enforce their own guards. One way this could be useful is to ask a user if they meant to navigate away, and cancel the navigation by passing false to next(); We also have access to the component’s this which allows us to use the component’s methods and properties in determining our routing logic.

const Swamp = {
  template: '<div>Swamp</div>',
  beforeRouteEnter(to, from, next) {
    console.log('Welcome to the swamp!');
    next();
  },
  beforeRouteLeave(to, from, next) {
    const answer =
      window.confirm('Are you sure you want to leave?');

    if (answer) {
      next();
    } else {
      next(false);
    }
  }
};

Please remember, as this code runs in the browser a user will have access to all code for your app regardless of Navigation Guards. When working on production applications always remember to implement proper validation and permission checking on the back-end!

Wrapping Up

We already know Vue Router is a great solution to provide routing in your Vue app, but today we’ve covered some advanced use-cases that Vue Router supports out-of-the-box. As always, make sure to review the official documentation. Check out some other advanced features such as Transitions to spice up your app or Lazy Loading Routes to increase performance.

  Tweet It

🕵 Search Results

🔎 Searching...