I has a similar issue with react-router-dom v6, but you can tweak it to your benefits
First create a source of truth wheither a user can or can't access some route, for roles based auth I'd think of a hook like
export function useUserRoles() {
// some logic or api call to get the roles
// for demonstration purposes it's just hard coded
const userRoles: Array<typeof UserRoles[number]> = ['admin', 'root'];
// return the current user roles
return userRoles;
}
Then we make a component that can decide using that hook weither to render the route or redirect to login(or some page)
export function RolesAuthRoute({ children, roles }: { children: ReactNode, roles: Array<typeof UserRoles[number]> }) {
const userRoles = useUserRoles();
const canAccess = userRoles.some(userRole => roles.includes(userRole));
if (canAccess)
return (
<Fragment>
{children}
</Fragment>
);
return (<Navigate to="/dashboard/login" />);
}
then the route defined wraps that component to act as a guard that decide if you can or can't access that route
<Route
path="users"
element={
<Suspense fallback={<ProjectLayoutLoader />}>
<RolesAuthRoute roles={['admin']}>
<ProjectUsersPage />
</RolesAuthRoute>
</Suspense>
} />