Role based react-router
What is the best way to conditionally render routes in react-router based on user role. I have a case where not all roles have permission to view certain routes. And also I need to deal with subroutes. So if one of main routes is something like /posts I want only admin and student to access that route and its subroutes (posts/today for example). I am using react-router version 5.3.2.
Solution 1:
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>
} />