Role-Based Sidebar Navigation in React Applications

Building dynamic sidebars is far from trivial. A maintainable and scalable solution requires a modern, well-structured approach — especially when dealing with multiple user roles and navigation scenarios. Without solid architecture, hardcoded components quickly become unmanageable as your application grows. Instead of relying on hardcoded items, you can define a sidebar configuration as data and render items dynamically based on user roles. Here’s a clean and extensible approach using TypeScript: type SidebarItem = { id: string title: string icon: keyof typeof Icons to: string allowedRoles: UserRole[] activeUrls?: string[] } const sidebarItems: SidebarItem[] = [ { id: "dashboard", title: t("labels.dashboard"), icon: "dashboard", to: "/dashboard", allowedRoles: [UserRole.COLLABORATOR, UserRole.USER, UserRole.WORKER], }, { id: "myJobs", title: t("labels.myJobs"), icon: "briefcase", to: "/my-jobs/current", activeUrls: ["/my-jobs/current", "/my-jobs/draft", "/my-jobs/completed"], allowedRoles: [UserRole.COLLABORATOR, UserRole.USER, UserRole.WORKER], }, { id: "exploreServices", title: t("labels.exploreServices"), icon: "search", to: "/post-a-job", allowedRoles: [UserRole.USER], }, { id: "myProfile", title: t("labels.myProfile"), icon: "user", to: "/my-profile", allowedRoles: [UserRole.WORKER], }, ] The SidebarItem type defines each item's structure — including id, title, icon, destination route (to), and the allowedRoles that determine visibility. The optional activeUrls helps match nested routes to highlight the correct item.

Jun 11, 2025 - 18:50
 0
Role-Based Sidebar Navigation in React Applications

Building dynamic sidebars is far from trivial. A maintainable and scalable solution requires a modern, well-structured approach — especially when dealing with multiple user roles and navigation scenarios. Without solid architecture, hardcoded components quickly become unmanageable as your application grows.

Instead of relying on hardcoded items, you can define a sidebar configuration as data and render items dynamically based on user roles. Here’s a clean and extensible approach using TypeScript:

type SidebarItem = {
  id: string
  title: string
  icon: keyof typeof Icons
  to: string
  allowedRoles: UserRole[]
  activeUrls?: string[]
}
const sidebarItems: SidebarItem[] = [
  {
    id: "dashboard",
    title: t("labels.dashboard"),
    icon: "dashboard",
    to: "/dashboard",
    allowedRoles: [UserRole.COLLABORATOR, UserRole.USER, UserRole.WORKER],
  },
  {
    id: "myJobs",
    title: t("labels.myJobs"),
    icon: "briefcase",
    to: "/my-jobs/current",
    activeUrls: ["/my-jobs/current", "/my-jobs/draft", "/my-jobs/completed"],
    allowedRoles: [UserRole.COLLABORATOR, UserRole.USER, UserRole.WORKER],
  },
  {
    id: "exploreServices",
    title: t("labels.exploreServices"),
    icon: "search",
    to: "/post-a-job",
    allowedRoles: [UserRole.USER],
  },
  {
    id: "myProfile",
    title: t("labels.myProfile"),
    icon: "user",
    to: "/my-profile",
    allowedRoles: [UserRole.WORKER],
  },
]

The SidebarItem type defines each item's structure — including id, title, icon, destination route (to), and the allowedRoles that determine visibility. The optional activeUrls helps match nested routes to highlight the correct item.