Search code examples
vue.jsvuejs3vue-routervue-router4

How to execute vue-router beforeEach ONE time?


I have an annoying situation where I need to hook into every route change to check something. If condition X is true, I need to redirect to the homepage by showing a notice only on that single pageview. So I have the following:

router.beforeEach(() => {
  if (...) {
    store.showIneligibleBanner();
    return { path: '/' };
  }
  // in all other cases hide the banner
  store.hideIneligibleBanner();
  return true;
});

The problem is when I return { path: '/' } this triggers the beforeEach a second time and the conditional no longer applies. I know I could create more variables to keep track but I wanted a cleaner approach.

I am really just trying to show a banner a single time on that return redirect.


Solution

  • In store's state, store two vars: hasBannerBeenShown and isBannerVisible

    router:

    // ...
    router.beforeEach((to, from, next) => {
      if (!store.hasBannerBeenShown && anyOtherFancyCondition) {
        store.hasBannerBeenShown = true;
        store.isBannerVisible = true;
        return { path: '/' };
      } 
      store.isBannerVisible && (store.isBannerVisible = false);
      next()
    });
    

    Note: The syntax above is based on the assumption you're using pinia. If you're using vuex, the syntax changes a bit (you'll need to commit mutations rather than assign to state), but the logic stays the same.