DEV Community

eugene musebe
eugene musebe

Posted on

Implementing Role-Based Access Control in Next.js App Router using Clerk Organizations

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 uses Organizations 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 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.

To see the completed application in action, visit 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 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

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

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

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.
    • 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

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode
  1. 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>
  );
}

Enter fullscreen mode Exit fullscreen mode
  1. 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

  1. 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>"
Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

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;

Enter fullscreen mode Exit fullscreen mode
  1. 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;

Enter fullscreen mode Exit fullscreen mode
  1. 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;

Enter fullscreen mode Exit fullscreen mode

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 ...

Enter fullscreen mode Exit fullscreen mode

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;

Enter fullscreen mode Exit fullscreen mode

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>
  );
}

Enter fullscreen mode Exit fullscreen mode

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;

Enter fullscreen mode Exit fullscreen mode

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;

Enter fullscreen mode Exit fullscreen mode

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 ...

Enter fullscreen mode Exit fullscreen mode

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

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)(.*)'],
};

Enter fullscreen mode Exit fullscreen mode

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;

Enter fullscreen mode Exit fullscreen mode

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>
  );
}

Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

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';
Enter fullscreen mode Exit fullscreen mode

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';
Enter fullscreen mode Exit fullscreen mode

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 };

Enter fullscreen mode Exit fullscreen mode

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';
Enter fullscreen mode Exit fullscreen mode

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

const { session } = useSession();
const userRole = checkUserRole(session);
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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';
Enter fullscreen mode Exit fullscreen mode

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();
Enter fullscreen mode Exit fullscreen mode

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]);
Enter fullscreen mode Exit fullscreen mode

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. 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 for in-depth details about the framework.

  2. Clerk Documentation: Explore Clerk's authentication capabilities and integration guides at 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.

Top comments (11)

Collapse
 
shiro15 profile image
Dovey

This is what i've been looking for ❤

Collapse
 
musebe profile image
eugene musebe

Glad you found the article helpful

Collapse
 
mihancode2gochistie profile image
Syed Md Mihan Chistie

Man this is even better than the original Clerk docs

Collapse
 
musebe profile image
eugene musebe

This warms my heart. Am glad you loved the article.

Collapse
 
nayem9b profile image
Md Razwan Niam

Just wow. Lots of thanks

Collapse
 
musebe profile image
eugene musebe

Delighted you found the article a gem! 😊 If you have any more questions or need further insights, feel free to ask. Happy to assist!

Collapse
 
l_nichols_4b77f33c095a19d profile image
L Nichols

userOrganizations is deprecated... now you have to use "userMemberships"

Collapse
 
musebe profile image
eugene musebe

Thanks for the update. I’ll update the project and documentation

Collapse
 
osimarex profile image
osimarex

I just get 'userMemberships.find is not a function' when i changed it from the deprecated 'organizationList'.

Collapse
 
ramybr profile image
ramybr

Can you provide a tutorial on how to make a user an admin (or a moderator if he's an admin) through the "Make Admin"/ "Make Moderator" buttons in the admin dashbord ? Much appreciated

Collapse
 
musebe profile image
eugene musebe

sure, let me see what I can do. I'll update you when. the article is done