2

I'm building a app with supabase. I have a route that receives query parameters from a email magic link and I want to validate those parameters on supabase service before I redirect to a target url (also a query parameter). Example:

const router = createRouter({
  history: createWebHistory("/"),
  routes: [
    {
      path: "/login",
      name: "login",
      beforeEnter: async (to) => {
        console.log("beforeEnter called");

        // Make request to supabase to validate parameters and login

        // Allow or deny
      },
      redirect: () => {
        console.log("redirect called");
        return { name: to.query.target };
      }
    },
    {
      path: "/",
      name: "home",
      component: Home,
      beforeEnter: () => {
        // Check supabase session
      }
    },
    // Other routes
  ]
});

Since I cant use async on the redirect function, I was hopping that I could use a vue-router guard, but beforeEnter and beforeEach are called after the redirect, therefore it does not works. Is there a way I can execute async code before redirecting?

Thanks.

guizo
  • 2,594
  • 19
  • 26

1 Answers1

2

As confirmed in the documentation,

Note that Navigation Guards are not applied on the route that redirects, only on its target. e.g. In the above example, adding a beforeEnter guard to the /home route would not have any effect.

It's unnecessary to use redirect, this is solved with beforeEnter hook that provides everything to do conditional redirects:

  beforeEnter: async (to) => {
    ...
    if (...)
      return  { name: to.query.target };
    
    return false;
  },
Estus Flask
  • 206,104
  • 70
  • 425
  • 565
  • Thanks. However it is strange that the `component` is required in Typescript since I'm always redirecting inside the `beforeEnter`. – guizo Feb 26 '23 at 03:23
  • That's not strange because it's presumed that the route may be navigated, beforeEnter could return true. View component is already resolved at this point. A dummy component can be provided. – Estus Flask Feb 26 '23 at 08:40
  • The strangeness is not that the `component` is required when using `beforeEnter`, but that there is no way around it. I was able to use `component: () => null`, which I think it is best than using a existing component. Anyway, I added [this idea](https://github.com/vuejs/router/discussions/1713) in vue-router repo. Thanks for the help. – guizo Feb 26 '23 at 16:20
  • You're welcome. It's typed in a way that makes sense for the majority of cases, https://unpkg.com/browse/vue-router@4.1.6/dist/vue-router.d.ts#L1013 , this one looks like edge case. Dummy component is `component: { render: () => null }`, will probably suit TS, or you can use type assertion – Estus Flask Feb 26 '23 at 18:58