Hello there, in this example l will show you how to create your own Role Guard for a Role based access without cluttering your code with many if statements which can be hard to manage and problematic in feature if you want to do some modifications. For maintainability, let’s create our reusable RoleGuard component to handle role based access cleanly.
Handling Role based access with multiple IF STATEMENTS can quickly become very unmanageable and cumbersome and as your app grows this can easily lead to breaking some of the basic rules of programming like DRY:
For simplicity and consistency access control across our App lets encapsulate our role based access control in a reusable component.
STEP 1
Here’s the RoleGuard.tsx component under utils folder:
import { Role } from “@/types”;
import { usePage } from “@inertiajs/react”;
interface RoleGuardProps {
roles: string | string[];
children: React.ReactNode;
}
export const RoleGuard = ({ roles, children }: RoleGuardProps) => {
const { auth } = usePage().props;
const roleArray = Array.isArray(roles) ? roles : [roles];
const hasRole = auth.user.roles.some((userRole: Role) => roleArray.includes(userRole.name));
return hasRole ? children : null;
}
Ensure your under @types folder on your types file creates a Role type which can be structured like this or anyway that corresponds with your backend.
Here is an example of my Role:
export type Role = {
id: number;
name: string;
guard_name: string;
created_at: string;
updated_at: string;
users_count?: number;
pivot: {
model_type: string;
model_id: number;
role_id: number;
};
permissions?: Permission[];
}
This type defines the structure of a role as retrieved from your Laravel backend.
Here’s how you can use the RoleGuard component in your React App:
As an example here on the dashboard page we have content for different Roles (Admin, [admin and SuperAdmin] and Editor), so here as you can see a component can be accessed by one role only or more passed as an array.
import { RoleGuard } from “@/utils/roleGuard”;
const Dashboard = () => {
return (
<div>
<h1>Dashboard</h1>
<RoleGuard roles=”Admin”>
<div className=”items-top flex space-x-2″>
<h2>Admin Content</h2>
<p>Only visible to users with the Admin role.</p>
</div>
</RoleGuard>
<RoleGuard roles={[“Admin”, “SuperAdmin”]}>
<div className=”items-top flex space-x-2″>
<h2>Admin & SuperAdmin Content</h2>
<p>Visible to Admin and SuperAdmin roles.</p>
</div>
</RoleGuard>
<RoleGuard roles=”Editor”>
<div className=”items-top flex space-x-2″>
<h2>Editor Content</h2>
<p>Only visible to users with the Editor role.</p>
</div>
</RoleGuard>
</div>
);
};
export default Dashboard;
Single Role: Here we wrap the content with <RoleGuard roles=”Admin”> so only the users with Admin role will see this section of the page.
Multiple Roles: Here we have to pass an array to roles like roles={[“Admin”, “SuperAdmin”]} so that it accommodates for multiple roles.
Children: So in simple terms any React node wrapped inside the RoleGuard component will automatically be rendered conditionally based on the user’s roles when it is passed.
By implementing a RoleGuard component, you can significantly simplify role-based access control in your React Inertia applications. It’s a scalable and maintainable solution that avoids cluttering your code with unnecessary if statements.