0

I am doing a routing based on the role of the user in nextjs. I did one hook which returnes true or false if a user is allowed to navigate in a route. I want to intercept that into _app.tsx file so I did the following thing:

_app.tsx

const App: React.FC<{
  Component: React.FC;
  pageProps: Record<string, any>;
}> = ({ Component, pageProps }) => {
  const router = useRouter();
  const user =
    typeof localStorage !== 'undefined'
      ? (JSON.parse(localStorage.getItem('user') ?? 'null') as
          | User
          | { role: undefined })
      : null;
  
  //useRouteProvider returns true/false
  const isUserAllowedOnRoute = useRouteProvider(router.pathname, user?.role);

  if (!isUserAllowedOnRoute) {
    window.location.replace('/');
    // I also tried router.push('/') and Router.push('/') but I can't use that into this file. 
  }
  return (
    //...
  );
};

export default App;

In this case the error is ReferenceError: window is not defined

Based on the value of isUserAllowedOnRoute, how can I redirect to a certain route from here?

Loudrous
  • 1,039
  • 10
  • 29
  • Maybe try wrapping all your code in an `useEffect`? – Usman Sabuwala Oct 17 '21 at 11:28
  • The problem is that I am not into a window, so window instance doesn't exist. In fact it throws me ReferenceError: window is not defined – Loudrous Oct 17 '21 at 11:37
  • The `window` object will be available inside the `useEffect`. As @MaxProgramming mentioned, try moving the redirect logic into a `useEffect`. – juliomalves Oct 17 '21 at 14:45
  • @juliomalves Yes it is true, but it shows me the page. If I go to a route only for one specific role and I am not logged in, it shows me that page for 1 second and it is not really nice to see – Loudrous Oct 17 '21 at 15:36
  • That's expected if you're doing client-side redirects. If you don't want the flash to happen move the redirect to the server-side (using `getServerSideProps` for instance) instead. Or don't show any content _until after_ the check for the redirect is done. – juliomalves Oct 17 '21 at 15:38
  • @MARiVS I would suggest going this way: 1. Add `loading` boolean state. (loading = true) 2. In return, check if `loading` is true, show a loading indicator. 3. In `useEffect`, check if the user exists, if it does, redirect the user. 4. If the user does not exist, set `loading` to false, and in the return, show user not found – Usman Sabuwala Oct 24 '21 at 08:13

0 Answers0