Have you ever needed to hide an admin delete button from a regular user in your React app? Doing this securely requires Role-Based Access Control, or RBAC for short.

RBAC is simply a way to restrict what users can see and do based on their assigned role, like 'admin' or 'member'.

  • What role-based access control actually means in code
  • How to type roles safely using TypeScript unions
  • How to create a reusable component to guard parts of your UI
  • Common pitfalls to avoid when managing permissions

Why Role-Based Access Control Matters

As your app grows, different users need different permissions. You don't want a standard customer deleting database records or seeing billing dashboards.

Hiding a button in the UI is only half the battle. You also need to protect your backend, but getting the frontend right makes your app feel polished and secure.

TypeScript development Photo by Mohammad Rahmani on Unsplash

Typing Roles with TypeScript

TypeScript helps us catch bugs before our code even runs. We can define an exact list of allowed roles using a union type, which is just a set of specific strings joined by a pipe symbol.

Here is how you can define your user types and a simple permission checker function:

type Role = 'admin' | 'editor' | 'viewer';

interface User {
  id: string;
  name: string;
  role: Role;
}

function canEditContent(user: User): boolean {
  return user.role === 'admin' || user.role === 'editor';
}

By typing our roles strictly, TypeScript will yell at us if we accidentally misspell a role like 'admint' later in our code.

Building a Guard Component

Now let us build a React component that only shows its children if the current user has the right permission.

Here is a working example of an Authorize component:

import React from 'react';

type Role = 'admin' | 'editor' | 'viewer';

interface AuthorizeProps {
  allowedRoles: Role[];
  userRole: Role;
  children: React.ReactNode;
}

export function Authorize({ allowedRoles, userRole, children }: AuthorizeProps) {
  if (!allowedRoles.includes(userRole)) {
    return null;
  }
  
  return <>{children}</>;
}

This component checks if the user's role is inside the list of allowed roles. If it is not, it renders nothing.

Common mistakes

The biggest mistake beginners make is relying on frontend checks for real security. If a user can see a button, they might still try to send requests to your API. Always validate user roles on your server too, because anyone can inspect and modify frontend code in their browser developer tools.

Another mistake is hardcoding role strings everywhere instead of using TypeScript types or constants. When your boss asks to rename 'admin' to 'super_admin', you will thank yourself for keeping roles in one place.

Open up one of your current React projects today and try wrapping an admin-only button in a simple role check component.