Redirect to requested page after login using vue-router

If route guard is setup as below

router.beforeEach((to, from, next) => {
    if (to.matched.some(record => record.meta.requiresAuth)) {
        if (!loggedIn) {
            next({
                path: "/login",
                query: { redirect: to.fullPath }
            });
        } else {
            next();
        }
    } else {
        next();
    }
});

The redirect query can be extracted and used upon successful login

let searchParams = new URLSearchParams(window.location.search);

if (searchParams.has("redirect")) {
  this.$router.push({ path: `${searchParams.get("redirect")}` });
} else this.$router.push({ path: "/dashboard" });

Following on from Matt C's answer, this is probably the simplest solution but there were a few issues with that post, so I thought it best to write a complete solution.

The destination route can be stored in the browser's session storage and retrieved after authentication. The benefit of using session storage over using local storage in this case is that the data doesn't linger after a broswer session is ended.

In the router's beforeEach hook set the destination path in session storage so that it can be retrieved after authentication. This works also if you are redirected via a third party auth provider (Google, Facebook etc).

router.js

// If user is not authenticated, before redirecting to login in beforeEach

sessionStorage.setItem('redirectPath', to.path)

So a fuller example might look something like this. I'm using Firebase here but if you're not you can modify it for your purposes:

router.beforeEach((to, from, next) => {
  const requiresAuth = to.matched.some(x => x.meta.requiresAuth);
  const currentUser = firebase.auth().currentUser;

  if (requiresAuth && !currentUser) {
    sessionStorage.setItem('redirectPath', to.path);
    next('/login');
  } else if (requiresAuth && currentUser) {
    next();
  } else {
    next();
  }
});

login.vue

In your login method, after authetication you will have a line of code that will send the user to a different route. This line will now read the value from session storage. Afterwards we will delete the item from session storage so that it is not accidently used in future (if you the user went directly to the login page on next auth for instance).

this.$router.replace(sessionStorage.getItem('redirectPath') || '/defaultpath');
sessionStorage.removeItem('redirectPath');

A fuller example might look like this:

export default Vue.extend({
  name: 'Login',
  data() {
    return {
      loginForm: {
        email: '',
        password: ''
      }
    }
  },
  methods: {
    login() {
      auth.signInWithEmailAndPassword(this.loginForm.email, this.loginForm.password).then(user => {

        //Go to '/defaultpath' if no redirectPath value is set
        this.$router.replace(sessionStorage.getItem('redirectPath') || '/defaultpath');

        //Cleanup redirectPath
        sessionStorage.removeItem('redirectPath');

      }).catch(err => {
        console.log(err);
      });
    },
  },
});

I know this is old but it's the first result in google and for those of you that just want it given to you this is what you add to your two files. In my case I am using firebase for auth.

Router

The key line here is const loginpath = window.location.pathname; where I get the relative path of their first visit and then the next line next({ name: 'Login', query: { from: loginpath } }); I pass as a query in the redirect.

router.beforeEach((to, from, next) => {
    const currentUser = firebase.auth().currentUser;
    const requiresAuth = to.matched.some(record => record.meta.requiresAuth);

    if (requiresAuth && !currentUser) {
        const loginpath = window.location.pathname;
        next({ name: 'Login', query: { from: loginpath } });
    } else if (!requiresAuth && currentUser) next('menu');
    else next();
});

Login Page

No magic here you'll just notice my action upon the user being authenticated this.$router.replace(this.$route.query.from); it sends them to the query url we generated earlier.

signIn() {
    firebase.auth().signInWithEmailAndPassword(this.email, this.password).then(
        (user) => {
            this.$router.replace(this.$route.query.from);
        },
        (err) => {
            this.loginerr = err.message;
        },
    );
},

I am going to be fleshing out this logic in more detail but it works as is. I hope this helps those that come across this page.


This can be achieved by adding the redirect path in the route as a query parameter.

Then when you login, you have to check if the redirect parameter is set:

  • if IS set redirect to the path found in param
  • if is NOT set you can fallback on root.

Put an action to your link for example:

onLinkClicked() {
    if(!isAuthenticated) {
        // If not authenticated, add a path where to redirect after login.
        this.$router.push({ name: 'login', query: { redirect: '/path' } });
    }
}

The login submit action:

submitForm() {
    AuthService.login(this.credentials)
        .then(() => this.$router.push(this.$route.query.redirect || '/'))
        .catch(error => { /*handle errors*/ })
}