[Vuejs]-Vue router beforeEach: caught in loop and cannot load login template

0👍

I originally posted a solution for vue-router v4.x here: https://stackoverflow.com/a/68009594/1219079

I repeat it here again, maybe it will be useful.

It make use of vue-router V4.x and a global beforeEach guard.

Remember: vue-router 4.x discourages the use of next() (https://next.router.vuejs.org/guide/advanced/navigation-guards.html#optional-third-argument-next).

The use cases are:

  1. user asks for https://app.com/ without being already authorized;
  2. user asks for https://app.com/ being already authorized;
  3. user asks for any available routing, which requires auth or not.

Routes:

const routes = [
  /**
   * Routes not requiring auth
   */
  {
    path: '/',
    component: () => import('layouts/NotAuthorizedLayout.vue'),
    children: [
      {
        path: 'login',
        name: 'LOGIN',
        component: () => import('pages/Login.vue') 
      },
      {
        path: 'emailsignup',
        component: () => import('pages/EmailSignup.vue') 
      },
      {
        path: 'forgottenpassword',
        component: () => import('pages/ForgottenPassword.vue') 
      }
    ]
  },

  /**
   * Routes requiring auth
   */
  {
    path: '/',
    component: () => import('layouts/AuthorizedLayout.vue'),
    meta: { requiresAuth: true },
    children: [
      { 
        path: 'authors',
        name: 'AUTHORS',
        component: () => import('pages/Authors.vue') 
      },
      { path: 'profile', component: () => import('pages/userProfile/index.vue') }
    ]
  }
];

beforeEach global guard:

  const redirectToLogin = route => {
    const LOGIN = 'LOGIN';
    if (route.name != LOGIN) {
      return { name: LOGIN, replace: true, query: { redirectFrom: route.fullPath } };
    }
  };

  const redirectToHome = route => {
    const DEFAULT = 'AUTHORS';
    return { name: DEFAULT, replace: true };
  };

  Router.beforeEach((to, from) => {
    const userIsAuthenticated = store.getters['authentication/userIsAuthenticated'];
    const requiresAuth = to.matched.some((route) => route.meta && route.meta.requiresAuth);

    if (!userIsAuthenticated && to.fullPath === '/') {
      return redirectToLogin(to);
    }

    if (!userIsAuthenticated && requiresAuth) {
      return redirectToLogin(to);
    }

    if (to.fullPath === '/') {
      return redirectToHome(to);
    }

    return true;
  });

Leave a comment