Implementing Role-Based Access Control in Next.js App Router using Clerk Organizations
Tags: clerk, authentication, nextjs
Published: 2023-07-31 18:52:21

---
title: Implementing Role-Based Access Control in Next.js App Router  using Clerk Organizations
published: true
description: Learn how to implement Role-Based Access Control (RBAC) in a Next.js app router using Clerk Organizations.
tags: Clerk , Authentication , Nextjs
# cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lqcc4ume5j51dosxrxgq.jpeg
# Use a ratio of 100:42 for best results.
# published_at: 2023-07-31 18:41 +0000
---

## Introduction 

It is crucial to protect user data and control access to various application features in the dynamic world of web development. RBAC, or role-based access control, has become a well-liked and successful method of controlling permissions within web applications. RBAC enables developers to design a customised and secure user experience by assigning specific roles to users and defining their access rights in accordance with those roles. In this article, we'll examine how RBAC is implemented in the Next.js App Router using Clerk, a cutting-edge platform for user management and authentication.

We will look at how [Clerk](https://clerk.com) uses [Organizations](https://clerk.com/docs/organizations/overview) to simplify user authentication and role assignment, thereby streamlining RBAC integration into Next.js applications. Following this comprehensive guide will equip developers to build web applications that prioritise security and provide a tailored experience to each user based on their assigned role.



## Prerequisites


Make sure you have the following prerequisites in place before implementing Role-Based Access Control in the app using Next.js and Clerk:

1. Fundamentals of web development (HTML, CSS, and JavaScript).
2. Basic understanding of React/Next.js.
3. Node.js and npm must be installed.
4. A code editor (Visual Studio Code).
5. Git for version control -  optional.
6. An account with [Clerk.com](https://clerk.com) for authentication.


With these prerequisites in place, you can use Clerk to implement Role-Based Access Control in your Next.js application. If you haven't met any of these requirements, take the time to do so before proceeding with the tutorial.


## Github Repository and Live Demo 

You can access the source code of the application on GitHub at [https://github.com/musebe/nextjs-clerk-organizations-rbac-authentication](https://github.com/musebe/nextjs-clerk-organizations-rbac-authentication). 

To see the completed application in action, visit [https://nextjs-clerk-organizations-rbac-authentication.vercel.app](https://nextjs-clerk-organizations-rbac-authentication.vercel.app).


## Setting up Clerk and Clerk Organizations

The first step in using Clerk is to create a Clerk account. You can do this by going to [clerk.com](https://clerk.com) and creating a free account. You will be prompted to create a new application within your account after signing in. This application will serve as your starting point for exploring and utilising Clerk's various features and capabilities, which are highlighted below.

![Clerk Dashboard](https://res.cloudinary.com/hackit-africa/image/upload/v1688676392/new-setup.png "Clerk Dashboard")

After signing in, click the 'Add application' button. Give your app a name and select all of the 'Social authentication' methods you want your users to use.

![Application](https://res.cloudinary.com/hackit-africa/image/upload/v1688676948/Application_name.png "Clerk Dashboard")

### Creating Clerk Organizations

Now, it's time to create an organization. In Clerk, organizations serve as shared accounts, enabling collaboration among members across shared resources. Within an organization, there are members with elevated privileges, responsible for managing access to the organization's data and resources. These privileged members have the authority to grant or revoke permissions, ensuring seamless cooperation and secure control over the organization's assets.

To create an organization in Clerk after logging in and being on the home dashboard, follow these steps:
    
1.  Click on the "Create Organization" button, and a new form or modal will appear, prompting you to provide the necessary information for the organization.
    
2.  Fill in the required details for the organization, such as the organization name, logo, and any other relevant information.
    
3.  Click on the `Create` button to finalize the creation of the organization.
    
4.  Clerk will then create the organization, and you will be redirected to the newly created organization's dashboard.


![Organizations Dashboard](https://res.cloudinary.com/hackit-africa/image/upload/v1690759651/create-org.png)


### Adding members to an Organization

To add members to the Clerk organization, follow these steps:

1.  Navigate to the `Members` section: After selecting the organization in Clerk's dashboard, navigate to the "Members" section, this is where user management is handled.
    
2.  Click on `Add Members`: Look for the "Add Members" button within the "Members" section and click on it to initiate the process.
    
3.  A pop-up form will appear: Once you click on "Add Members," a pop-up window will show up on your screen, providing a form to input the necessary details.
    
4.  Search for the user: In the pop-up form, you can search for the specific user you want to add to the organization. Enter their email address or username in the search field.
    
5.  Choose a role: For each user you add, you can assign them a role within the organization. Clerk typically offers two roles: `admin` and `basic_member`. Select the appropriate role for the user based on their level of access and permissions.
 
 - admin - The `admin` role grants complete access to all organisational resources. Members with the admin role have administrator privileges and can fully manage organisations and memberships in organisations.
- basic_member - The `basic_member` role is the default role for an organization's users. The availability of organisational resources is restricted. Basic members cannot manage organisations or memberships in organisations, but they can view information about the organisation and its members.
6.  Click `Add` : Once you have verified the details, click the "Add" or "Confirm" button to finalize the addition of the user to the organization with the specified role.


![Add Member](https://res.cloudinary.com/hackit-africa/image/upload/v1690762184/members.png)

Congratulations! You have successfully created an organization in Clerk. From the organization dashboard, you can manage users, roles, and other resources associated with the organization.

## Next.js Setup

Now to the fun part! Let's spin up a new Next.js project to get started with implementing Role-Based Access Control (RBAC). To do this, simply navigate to the directory of your choice and run the following command in your terminal or command prompt:

```
npx create-next-app my-rbac-app
```

Replace `my-rbac-app` with your desired project name. This command will set up a new Next.js project for you with all the necessary configurations to begin building your RBAC-enabled web application.

The best part is that starting from Next.js version 13, Tailwind CSS comes pre-configured by default, saving you the trouble of installing it separately. With Next.js and Tailwind CSS ready to go, you can now focus on integrating RBAC using Clerk into your freshly created Next.js project. So, let's get started and secure your web application with personalized user access and permissions!

## Integrating Clerk with Next.js

The next step after creating the Next.js project and having Tailwind CSS set up is to integrate Clerk into your application for handling user authentication and role-based access control. Follow these steps to proceed:

1.  Install Clerk SDK: Use npm or yarn to install the Clerk SDK in your Next.js project. The Clerk SDK provides the necessary tools to authenticate users and manage roles. Run the following command in your project's root directory:

```
npm install @clerk/nextjs
```
2. Initialize Clerk in your Next.js App: Import the Clerk SDK into your Next.js application and initialize it with your Clerk API credentials. This step enables your application to interact with Clerk's authentication services. In Next 13 using the app router, the initialization is done in the `layout.js`  file as highlighted below : 

```
// app/layout.js
import '@styles/globals.css';
import { ClerkProvider } from '@clerk/nextjs';


export const metadata = {
  title: 'Clerk-Organizations',
  description: 'Clerk Role-Based Authentication Using Organizations',
};

export default function RootLayout({ children }) {
  return (
    <ClerkProvider>
      <html lang='en'>
        <body>
          <div className='main'>
            <div className='gradient' />
          </div>
          <main className='app'>
            {children}
          </main>
        </body>
      </html>
    </ClerkProvider>
  );
}

```

3. Obtain Clerk API Credentials: To initialize the Clerk SDK, you'll need API credentials specific to your Clerk organization. Retrieve these credentials from the Clerk dashboard on the left sidebar under the `API Keys` tab. Copy the keys and paste them in the `.env` file we are going to create .

![Api_Keys](https://res.cloudinary.com/hackit-africa/image/upload/v1688677690/API-Keys.png "Clerk Dashboard")

4. In your Next.js project's root directory, generate a new file named `.env.local`. Once created, paste the `CLERK_PUBLISHABLE_KEY` and `CLERK_SECRET_KEY` environment variables that you previously copied from the Clerk dashboard into this `.env.local` file. Storing these keys in the `.env.local` file ensures that your sensitive credentials are securely accessible by your Next.js application during runtime, safeguarding them from being exposed in your codebase. Remember to refrain from sharing or committing the `.env.local` file to version control to maintain the confidentiality of your environment variables.


```
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY="<Your Publishable Key>"
CLERK_SECRET_KEY="<Your Clerk Secret Key>"
```

Having completed the setup and configurations as described above, it is now time to begin establishing the application layout in the project.


## Application Layout

The next step is to create the application layout and pages. We will organize our pages using the folder-based approach provided by Next.js 13. Inside the `app` directory, we shall create three separate folders named `Profile`, `Users`, and `Admin`, each containing a `page.jsx` file. These files will serve as the components for our respective pages. In the `Profile` page, we will provide users with personalized information and options to manage their accounts. The `Users` page will display general user-related data and interactions. Lastly, the `Admin` page will serve as a dashboard for administrators, granting them access to oversee and control various aspects of the application. This organized structure will enhance code maintainability and make it easier to extend our Next.js app as it grows in functionality.

Inside the `app` directory, create three separate folders for each page: `Profile`, `Users`, and `Admin`. Within each folder, create a `page.jsx` file with the content for each page.
    

Here's how you directory structure should look like :

```
- your-nextjs-app
  - app
    - profile
      - page.jsx
    - users
      - page.jsx
    - admin
      - page.jsx

```
Now, let's update the content of each `page.jsx` file accordingly:

1.  `Profile/page.jsx`:

```
const Profile = () => {
  return (
    <div>
      <h1>Welcome to the Profile Page!</h1>
      {/* Add any content or components specific to the Profile page here */}
    </div>
  );
};

export default Profile;

```

2. `Users/page.jsx`:

```
const Users = () => {
  return (
    <div>
      <h1>Welcome to the Users Page!</h1>
      {/* Add any content or components specific to the Users page here */}
    </div>
  );
};

export default Users;

```
3. `Admin/page.jsx`:

```
const Admin = () => {
  return (
    <div>
      <h1>Welcome to the Admin Page!</h1>
      {/* Add any content or components specific to the Admin page here */}
    </div>
  );
};

export default Admin;

```
Now, the pages will be accessible using the following URLs:

-   Profile: `http://localhost:3000/profile`
-   Users: `http://localhost:3000/users`
-   Admin: `http://localhost:3000/admin`

This organized approach will ensure a clear separation of concerns and make it easier to manage and scale your Next.js app.

### Navbar 

Onto the Navbar! Let's begin by creating a `components` folder at the root of your Next.js app. Inside this new folder, we will place a file named `Navbar.jsx` to contain our Navbar component. This step will help us organize and manage reusable components more efficiently.

Here's what the folder structure will look like after completing this step:

```
- your-nextjs-app
  - components
    - Navbar.jsx
  - app
    - Profile
      - page.jsx
    - Users
      - page.jsx
    - Admin
      - page.jsx
  - pages
    ... other pages if any ...

```

Once the `components` folder is created, paste the content below into the new `Navbar.jsx` file located inside the `components` folder.
```
import Link from 'next/link';

const Navbar = () => {
  const links = [
    { title: 'Profile', url: '/profile' },
    { title: 'Dashboard', url: '/user' },
    { title: 'Admin Dashboard', url: '/admin', role: 'admin' },
    // Add more placeholder links as needed
  ];

  return (
    <header className='text-gray-600 body-font bg-white shadow'>
      <div className='container mx-auto flex flex-wrap p-5 flex-col md:flex-row items-center justify-between'>
        <div className='flex items-center'>
          <a
            href='/'
            className='flex title-font font-medium items-center text-gray-900'
          >
            <svg
              xmlns='http://www.w3.org/2000/svg'
              fill='none'
              stroke='currentColor'
              strokeLinecap='round'
              strokeLinejoin='round'
              strokeWidth='2'
              className='w-10 h-10 text-white p-2 bg-indigo-500 rounded-full'
              viewBox='0 0 24 24'
            >
              <path d='M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5'></path>
            </svg>
            <span className='ml-3 text-xl'>SecureClerk</span>
          </a>
        </div>
        <nav className='md:ml-auto md:mr-auto flex flex-wrap items-center text-base justify-center'>
          <Link href='/profile'>
            <div className='mr-5 cursor-pointer hover:text-gray-900'>
              Profile
            </div>
          </Link>
          <Link href='/user'>
            <div className='mr-5 cursor-pointer hover:text-gray-900'>
              Dashboard
            </div>
          </Link>
          <Link href='/admin'>
            <div className='mr-5 cursor-pointer hover:text-gray-900'>
              Admin Dashboard
            </div>
          </Link>
          {/* Add more links directly here as needed */}
        </nav>
        <div className='md:flex items-center'>
          <a href='/sign-in'>
            <button className='text-white bg-indigo-500 border-0 py-2 px-4 focus:outline-none hover:bg-indigo-600 rounded text-base mr-4'>
              Login
            </button>
          </a>
          <a href='/sign-up'>
            <button className='text-white bg-indigo-500 border-0 py-2 px-4 focus:outline-none hover:bg-indigo-600 rounded text-base'>
              Sign Up
            </button>
          </a>
        </div>
      </div>
    </header>
  );
};

export default Navbar;

```

The next step is to modify the `Layout.js` file to include the `Navbar` component so that it can be used by the entire app. We'll import the `Navbar` component into the `Layout.js` file and render it within the layout structure. This way, the `Navbar` will be present across all pages wrapped within the `RootLayout`.

Here's the updated `Layout.js` file:

```
// app/Layout.js
import '@styles/globals.css';
import { ClerkProvider } from '@clerk/nextjs';
import Navbar from '../components/Navbar'; // Import the Navbar component

export const metadata = {
  title: 'Clerk-Organizations',
  description: 'Clerk Role-Based Authentication Using Organizations',
};

export default function RootLayout({ children }) {
  return (
    <ClerkProvider>
      <html lang='en'>
        <body>
          <div className='main'>
            <div className='gradient' />
          </div>
          <main className='app'>
            <Navbar /> {/* Include the Navbar component here */}
            {children}
          </main>
        </body>
      </html>
    </ClerkProvider>
  );
}

```
With this in place, the Navbar component provides a user-friendly navigation interface for our Next.js app. It includes links for "Profile," "Dashboard," and "Admin Dashboard," enabling seamless client-side navigation to the corresponding pages when clicked.


##  Sign in and sign up Components

Clerk offers a selection of pre-built components that seamlessly integrate sign-in, sign-up, and other user management features into your Next.js application. To leverage these functionalities, you can utilize the `<SignIn />` and `<SignUp />` components along with Next.js' optional catch-all route.

To implement this, within the "app" folder of your project, create two new directories named "sign-up" and "sign-in." Inside each directory, place the corresponding code for the sign-up and sign-in functionalities following this structure: `sign-up/[[...sign-up]]/page.jsx`.

Below, find the code for the Sign In and Sign Up components using the Clerk components provided by `@clerk/nextjs`.

### Sign In Component:

```
// app/sign-in/[[...sign-in]]/page.tsx
import { SignIn } from '@clerk/nextjs';

const SignInPage = () => {
  return (
    <div>
      <h1>Sign In</h1>
      <SignIn />
    </div>
  );
};

export default SignInPage;

```

### Sign Up Component:

```
// app/sign-up/[[...sign-up]]/page.tsx
import { SignUp } from '@clerk/nextjs';

const SignUpPage = () => {
  return (
    <div>
      <h1>Sign Up</h1>
      <SignUp />
    </div>
  );
};

export default SignUpPage;

```
After adding the two pages, the updated project directory structure will look like this:

```
- your-nextjs-app
  - components
    - Navbar.jsx
  - app
    - Profile
      - page.jsx
    - Users
      - page.jsx
    - Admin
      - page.jsx
    - sign-up
      - [[...sign-up]]
        - page.tsx
    - sign-in
      - [[...sign-in]]
        - page.tsx
  - pages
    ... other pages if any ...

```

With the setup completed, when you visit the route `http://localhost:3000/sign-in`, you will be able to load Clerk's login page, as demonstrated below:

![Application](https://res.cloudinary.com/hackit-africa/image/upload/v1688682376/clerk.png)


## Protecting your application routes

It's time to decide which pages are public and which require authentication now that Clerk has been installed and mounted in your application. We achieve this by declaring the public and private routes in a file called `middleware.js` at the project's root. In our situation, we only want the home page to be viewable by the general public and the remaining portions of the page to be hidden until the user logs into the application. The code below makes it possible to achieve this:

```
import { authMiddleware } from '@clerk/nextjs';

export default authMiddleware({
  publicRoutes: ["/"]
});

export const config = {
  matcher: ['/((?!.*\\..*|_next).*)', '/', '/(api|trpc)(.*)'],
};

```


## Hero Component

To finalize the layout, let's beautify the homepage by adding some content to it. We'll start by creating a `Hero.jsx` page in the `components` folder and then embed it into the `page.jsx` file located inside the `app` directory.

This component will serve as the hero section of the homepage.

```
// components/Hero.jsx
const Hero = () => {
  return (
    <div className="hero">
      {/* Your hero content and layout here */}
      <h1>Welcome to Our Website</h1>
      <p>Discover amazing things with us!</p>
    </div>
  );
};

export default Hero;

```
Next, go to the `page.jsx` file inside the `app` directory and update it to include the `Hero` component:

```
// app/page.jsx
import { Hero } from "@components";

export default function Home() {
  return (
    <main className='overflow-hidden'>
      <Hero />
      {/* Other content and components for the Home page can be added here */}
    </main>
  );
}

```
Now, with the `Hero` component embedded in the `Home` page, you have a beautiful hero section displayed at the top of the homepage. You can further enhance the layout by adding additional content and components to the `Home` page as needed. This will create an engaging and visually appealing homepage for your Next.js app.

Your Final project structure should look like this upto this point : 

```
- your-nextjs-app
  - components
    - Hero.jsx
    - Navbar.jsx
  - app
    - profile
      - page.jsx
    - users
      - page.jsx
    - admin
      - page.jsx
    - sign-up
      - [[...sign-up]]
        - page.tsx
    - sign-in
      - [[...sign-in]]
        - page.jsx
    - layout.jsx
    - page.jsx
  - styles
    - globals.css
  - node_modules
  - public
    - favicon.ico
    ... other public files ...
  - package.json
  - next.config.js

```

## Navbar links Conditional Rendering 

For conditional link rendering, we will utilize Clerk's `SignedOut`, `UserButton`, and `SignedIn` components. When a user is not signed in, we will display only the "Login" and "Sign Up" buttons. However, once the user is logged in, we will show the navigation links alongside Clerk's `UserButton` component, which facilitates the sign-out functionality. This approach enables us to dynamically adjust the content displayed in the Navbar based on the user's authentication status.

To achieve this functionality, on the Navbar component, import the following components from Clerk's Next.js library:

```
import { SignedOut, UserButton, SignedIn } from '@clerk/nextjs';
```

These components will allow you to conditionally render content based on the user's authentication status, enabling you to show different elements for signed-in and signed-out users in the Navbar.

After logging in, it becomes necessary to verify the user's role, distinguishing between "admin" and "basic_member," and accordingly display the "Profile" and "Dashboard" links only for "basic_member," while showing all links for "admin." We can obtain this information using Clerk's `useSession` hook, which allows access to the session status. To achieve this, simply include the `useSession` hook within the Clerk object you previously imported. By doing so, you will be able to fetch the user's role from the session data and conditionally render the appropriate links in the Navbar.

```
import { SignedOut, UserButton, SignedIn, useSession } from '@clerk/nextjs';
```

To simplify the role-checking process, let's create a utility function that will iterate through the session data and return the user's role. To do this, create a new folder named `utils` at the root of the project and add a file called `userUtils.js` inside it. In `userUtils.js`, implement the following function:

```
function checkUserRole(session) {
  if (
    !session ||
    !session.user ||
    !session.user.organizationMemberships ||
    session.user.organizationMemberships.length === 0
  ) {
    return null; // Return null if the user is not a basic member
  }

  const organizationMemberships = session.user.organizationMemberships;

  // Loop through all organization memberships
  for (const membership of organizationMemberships) {
    if (membership.role) {
      return membership.role.toLowerCase(); // Return the role in lowercase if it exists
    }
  }

  return null; // Return null if no role is found in the memberships
}

export { checkUserRole };

```

This function will allow us to extract and determine the user's role from the session data, making it easier to handle role-based actions in the application.

The next step is to export the `checkUserRole` function from the `userUtils.js` file so that it can be used in the `Navbar` component. To achieve this, use the following import statement in the `Navbar` component:

```
import { checkUserRole } from '../utils/userUtils';
```

Inside the `Navbar` component, we can determine the user's role from the session data as follows:

```
const { session } = useSession();
const userRole = checkUserRole(session);
```
By utilizing the `useSession` hook from Clerk, we retrieve the user's session data. Then, we call the `checkUserRole` function with the `session` parameter, which enables us to obtain the user's role. This way, we can efficiently check the user's role within the `Navbar` component and conditionally render the appropriate links based on the role information.

  
After the user has signed in, we can utilize the `userRole` information to determine which links should be displayed for administrators and basic members.

```
<SignedIn>
  {links.map((link) =>
    (link.role === 'admin' && userRole === 'admin') || !link.role ? (
      <Link key={link.title} href={link.url}>
        {/* Use a div instead of an anchor tag */}
        <div className='mr-5 cursor-pointer hover:text-gray-900'>
          {link.title}
        </div>
      </Link>
    ) : null
  )}
</SignedIn>
```

When the user is signed in, the `SignedIn` component allows us to conditionally render the navigation links based on the user's role. The `links.map` function iterates through the `links` array, and for each link, it checks if the link is intended for administrators (`link.role === 'admin'`) and if the user actually has an "admin" role (`userRole === 'admin'`). If both conditions are met or if the link does not have a specific role assigned (`!link.role`), the link is displayed using the `Link` component from Next.js, enclosed within a `div` element for proper styling. This way, we can selectively show the appropriate links based on the user's role after they have signed in.


Here's how you should arrange the `SignedOut` and `UserButton` components:

```
{/* SignedOut Component */}
<SignedOut>
  <a href='/sign-in'>
    <button className='text-white bg-indigo-500 border-0 py-2 px-4 focus:outline-none hover:bg-indigo-600 rounded text-base mr-4'>
      Login
    </button>
  </a>
  <a href='/sign-up'>
    <button className='text-white bg-indigo-500 border-0 py-2 px-4 focus:outline-none hover:bg-indigo-600 rounded text-base'>
      Sign Up
    </button>
  </a>
</SignedOut>

{/* UserButton Component */}
<SignedIn>
  <div className='ml-4'>
    <UserButton afterSignOutUrl='/' />
  </div>
</SignedIn>
```

Having completed all the necessary steps, we are now able to conditionally render the application, displaying different links based on the various scenarios we have highlighted. This allows us to customize the Navbar content depending on the user's authentication status, role, and whether they are signed in or signed out. With this implementation, the application provides a seamless and user-specific navigation experience.

## Ensuring Role-Based Access Control for the Admin    Dashboard Page

Currently, we have successfully hidden the `Admin Dashboard` link from basic members. However, there is still an issue to address - any user can access the `/admin` route, even if they are not authorized to do so. This behavior is undesirable and needs to be rectified. Let's proceed to handle this situation to ensure that only users with the `admin` role can access the `Admin Dashboard` page.

To implement this functionality, we will utilize the `useOrganizationList` hook on the admin page. By using the `useOrganizationList` hook, we gain access to the list of available Organizations and the OrganizationMemberships to which the user is affiliated. This information will enable us to enforce role-based access control and ensure that only authorized users can access the Admin Dashboard page.

We must first import the `useOrganizationList` hook into the admin page before we can use it. Here's how to go about it:

```
import { useOrganizationList } from '@clerk/nextjs';
```

After importing the `useOrganizationList` hook, you can utilize it to access the organization data. By invoking the hook, you will receive three variables: `organizationList`, `isLoaded`, and `setActive`.

```
const { organizationList, isLoaded, setActive } = useOrganizationList();
```

`organizationList` will hold the list of available organizations, providing important information about each organization and its members. `isLoaded` is a boolean value that indicates whether the organization data has been successfully loaded and is ready for use. Lastly, `setActive` is a function that allows you to set the active organization.

The subsequent step involves waiting for the organization data to load and verifying whether the user's role is not admin. We achieve this using the `useEffect` hook:

```
useEffect(() => {
  if (isLoaded) {
    // Find the admin organization from the loaded organization list
    const adminOrganization = organizationList.find(
      (org) => org.membership.role === 'admin'
    );

    // If the user is not an admin, redirect to the homepage
    if (!adminOrganization || adminOrganization.membership.role !== 'admin') {
      router.push('/'); // Replace '/' with the homepage URL
    } else {
      // If the user is an admin, no need to wait for the organization list; render the admin page directly
      setShowLoader(false);
    }
  }
}, [isLoaded, organizationList]);
```
In this `useEffect` block, we use the `isLoaded` variable to ensure that we have successfully loaded the organization data. Once the data is available, we look for an organization with the role of 'admin' within the organization list. If the user does not have an admin role or there is no admin organization found, we redirect them to the homepage using the `router.push` method. However, if the user is indeed an admin, we proceed to render the admin page directly, setting `setShowLoader` to `false` to indicate that the loading process is complete. This way, we enforce the role-based access control and appropriately handle navigation based on the user's role.

## Conclusion 

With these steps, we have successfully implemented Role-Based Access Control in the Next.js App Router using Clerk Organizations. It demonstrates how seamlessly Clerk's features can be integrated into the application, making the process straightforward and efficient. This approach allows us to control user access based on their roles, providing a secure and tailored user experience. Indeed, the integration with Clerk Organizations simplifies the implementation of role-based access, making it a smooth and straightforward process.

If you prefer not to create organizations through the Clerk dashboard, the Clerk team offers components that you can integrate directly into your codebase to handle organization management. For more details, you can explore the documentation at: [https://clerk.com/docs/organizations/overview](https://clerk.com/docs/organizations/overview). These components provide a convenient way to manage organizations and memberships within your application, giving you flexibility and control over the organization setup process.

## Refference 

For further guidance and information, refer to the following:

1.  Next.js Documentation: Access the official Next.js documentation at [https://nextjs.org/docs](https://nextjs.org/docs) for in-depth details about the framework.
    
2.  Clerk Documentation: Explore Clerk's authentication capabilities and integration guides at [https://clerk.com/docs](https://clerk.com/docs) to understand its usage better.
    
3.  Simplifying Authentication in Next.js Applications with Clerk: Find detailed steps for setting up Clerk authentication in Next.js apps in the blog post: [Dev.to Link](https://dev.to/musebe/simplifying-authentication-in-nextjs-applications-with-clerk-3adh).