Docs

Organization membership requests

These methods on the Organization object allow you to manage the membership requests for an organization.

The following examples assume:

getMembershipRequests()

Retrieve the list of membership requests for the currently active organization.

function getMembershipRequests: (params?: GetMembershipRequestParams) => Promise<ClerkPaginatedResponse<OrganizationMembershipRequestResource>>;
  • Name
    initialPage?
    Type
    number
    Description

    A number that can be used to skip the first n-1 pages. For example, if initialPage is set to 10, it is will skip the first 9 pages and will fetch the 10th page.

  • Name
    pageSize?
    Type
    number
    Description

    A number that indicates the maximum number of results that should be returned for a specific page.

  • Name
    status?
    Type
    string
    Description

    The status of the membership requests that will be included in the response.

getMembershipRequests() returns

TypeDescription
Promise<ClerkPaginatedResponse<OrganizationMembershipRequestResource>>This method returns a Promise that resolves to a ClerkPaginatedResponse of OrganizationMembershipRequest objects.

Example

The following example demonstrates how to use the getMembershipRequests() method to render a table of membership requests for the active organization. To ease the development process, the response or error message of a method will be displayed on the user interface.

For the following example, your HTML file should look like this:

index.html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Clerk + JavaScript App</title>
    <style>
      /* Style for the table */
      table {
        border-collapse: collapse; /* Collapse borders into a single border */
        border: 1px solid black; /* Border for the entire table */
      }
      /* Style for table cells */
      td,
      th {
        border: 1px solid black; /* Border for each cell */
        padding: 2px; /* Optional: Add padding to cells */
      }
    </style>
  </head>
  <body>
    <div id="app"></div>

    <p id="error-container" hidden>
      Error:
      <span id="error-message"></span>
    </p>

    <h2>Membership Requests</h2>
    <table id="requests_table">
      <thead>
        <tr>
          <th>User ID</th>
          <th>Identifier</th>
          <th>Status</th>
          <th id="add-member-head" hidden>Add member</th>
        </tr>
      </thead>
      <tbody id="requests_table_body"></tbody>
    </table>

    <p>Response:</p>
    <pre id="response"></pre>

    <script type="module" src="/main.js"></script>
  </body>
</html>

And your JavaScript file should look like this:

main.js
import Clerk from '@clerk/clerk-js';

// Initialize Clerk with your Clerk publishable key
const clerk = new Clerk('YOUR_PUBLISHABLE_KEY');
await clerk.load();

if (clerk.user) {
  // Check for an active organization
  if (clerk.organization) {
    // Render list of organization membership requests
    async function renderMembershipRequests(organization, isAdmin) {
      try {
        const { data } = await organization.getMembershipRequests();
        const membershipRequests = data;
        console.log(`getMembershipRequests:`, membershipRequests);

        membershipRequests.map((membershipRequest) => {
          const requestsTable = document.getElementById("requests_table");
          const row = requestsTable.insertRow();
          row.insertCell().textContent =
            membershipRequest.publicUserData.userId;
          row.insertCell().textContent =
            membershipRequest.publicUserData.identifier;
          row.insertCell().textContent = membershipRequest.status;

          // Add administrative actions:
          // Add member (removes request)
          if (isAdmin) {
            // Show add member button
            document.getElementById("add-member-head").removeAttribute("hidden");

            // Get the user ID of the member
            const userId = membershipRequest.publicUserData.userId;

            // Add member to organization
            const addBtn = document.createElement("button");
            addBtn.textContent = "Add member";
            addBtn.addEventListener("click", async function (e) {
              e.preventDefault();

              const role = "org:member";

              await organization.addMember({ userId, role })
                .then((res) => {
                  document.getElementById("response").innerHTML =
                    JSON.stringify(res);
                })
                .catch((error) => {
                  document.getElementById("error-container").removeAttribute("hidden");
                  document.getElementById("error-message").innerHTML =
                    error.errors[0].longMessage;
                  console.log("An error occurred:", error.errors);
                });
            });
            row.insertCell().appendChild(addBtn);
          }
        });
      } catch (error) {
        document.getElementById("error-container").removeAttribute("hidden");
        document.getElementById("error-message").innerHTML =
          error.errors[0].longMessage;
        console.log("An error occurred:", error.errors);
      }
    }

    /**
     * Checks if a user is an admin of the
     * currently active organization and
     * renders the organization's membership requests.
     */
    async function checkAdminAndRenderRequests() {
      const organizationId = clerk.organization.id;

      const organizationMemberships =
        await clerk.user.getOrganizationMemberships();

      const currentMembership = organizationMemberships.find(
        (membership) => membership.organization.id === organizationId
      );
      const currentOrganization = currentMembership.organization;

      if (!currentOrganization) {
        return;
      }
      const isAdmin = currentMembership.role === "org:admin";

      console.log(`Organization:`, currentOrganization);

      renderMembershipRequests(currentOrganization, isAdmin);
    }

    checkAdminAndRenderRequests();
  } else {
    // If there is no active organization,
    // mount Clerk's <OrganizationSwitcher />
    // to allow the user to set an organization as active
    document.getElementById("app").innerHTML = `
      <h2>Select an organization to set it as active</h2>
      <div id="org-switcher"></div>
    `;

    const orgSwitcherDiv = document.getElementById("org-switcher");

    clerk.mountOrganizationSwitcher(orgSwitcherDiv);
  }
} else {
  document.getElementById("app").innerHTML = `
    <div id="sign-in"></div>
  `;

  const signInDiv = document.getElementById("sign-in");

  clerk.mountSignIn(signInDiv);
}
index.html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Clerk + JavaScript App</title>
    <style>
      /* Style for the table */
      table {
        border-collapse: collapse; /* Collapse borders into a single border */
        border: 1px solid black; /* Border for the entire table */
      }
      /* Style for table cells */
      td,
      th {
        border: 1px solid black; /* Border for each cell */
        padding: 2px; /* Optional: Add padding to cells */
      }
    </style>
  </head>
  <body>
    <div id="app"></div>

    <p id="error-container" hidden>
      Error:
      <span id="error-message"></span>
    </p>

    <h2>Membership Requests</h2>
    <table id="requests_table">
      <thead>
        <tr>
          <th>User ID</th>
          <th>Identifier</th>
          <th>Status</th>
          <th id="add-member-head" hidden>Add member</th>
        </tr>
      </thead>
      <tbody id="requests_table_body"></tbody>
    </table>

    <p>Response:</p>
    <pre id="response"></pre>

    <!-- Initialize Clerk with your
    Clerk Publishable key and Frontend API URL -->
    <script
      async
      crossorigin="anonymous"
      data-clerk-publishable-key="YOUR_PUBLISHABLE_KEY"
      src="https://YOUR_FRONTEND_API_URL/npm/@clerk/clerk-js@latest/dist/clerk.browser.js"
      type="text/javascript"
    ></script>

    <script>
      window.addEventListener("load", async function () {
        await Clerk.load();
        if (Clerk.user) {
          // Check for an active organization
          if (Clerk.organization) {
            // Render list of organization membership requests
            async function renderMembershipRequests(organization, isAdmin) {
              try {
                const { data } = await organization.getMembershipRequests();
                const membershipRequests = data;
                console.log(`getMembershipRequests:`, membershipRequests);

                membershipRequests.map((membershipRequest) => {
                  const requestsTable = document.getElementById("requests_table");
                  const row = requestsTable.insertRow();
                  row.insertCell().textContent =
                    membershipRequest.publicUserData.userId;
                  row.insertCell().textContent =
                    membershipRequest.publicUserData.identifier;
                  row.insertCell().textContent = membershipRequest.status;

                  // Add administrative actions:
                  // Add member (removes request)
                  if (isAdmin) {
                    // Show add member button
                    document.getElementById("add-member-head").removeAttribute("hidden");

                    // Get the user ID of the member
                    const userId = membershipRequest.publicUserData.userId;

                    // Add member to organization
                    const addBtn = document.createElement("button");
                    addBtn.textContent = "Add member";
                    addBtn.addEventListener("click", async function (e) {
                      e.preventDefault();

                      const role = "org:member";

                      await organization.addMember({ userId, role })
                        .then((res) => {
                          document.getElementById("response").innerHTML =
                            JSON.stringify(res);
                        })
                        .catch((error) => {
                          document.getElementById("error-container").removeAttribute("hidden");
                          document.getElementById("error-message").innerHTML =
                            error.errors[0].longMessage;
                          console.log("An error occurred:", error.errors);
                        });
                    });
                    row.insertCell().appendChild(addBtn);
                  }
                });
              } catch (error) {
                document.getElementById("error-container").removeAttribute("hidden");
                document.getElementById("error-message").innerHTML =
                  error.errors[0].longMessage;
                console.log("An error occurred:", error.errors);
              }
            }
            /**
            * Checks if a user is an admin of the
            * currently active organization and
            * renders the organization's membership requests.
            */
            async function checkAdminAndRenderRequests() {
              const organizationId = Clerk.organization.id;

              const organizationMemberships =
                await Clerk.user.getOrganizationMemberships();

              const currentMembership = organizationMemberships.find(
                (membership) => membership.organization.id === organizationId
              );

              const currentOrganization = currentMembership.organization;

              if (!currentOrganization) {
                return;
              }

              const isAdmin = currentMembership.role === "org:admin";

              console.log(`Organization:`, currentOrganization);

              renderMembershipRequests(currentOrganization, isAdmin);
            }
            checkAdminAndRenderRequests();
          } else {
            // If there is no active organization,
            // mount Clerk's <OrganizationSwitcher />
            // to allow the user to set an organization as active
            document.getElementById("app").innerHTML = `
              <h2>Select an organization to set it as active</h2>
              <div id="org-switcher"></div>
            `;

            const orgSwitcherDiv = document.getElementById("org-switcher");

            Clerk.mountOrganizationSwitcher(orgSwitcherDiv);
          }
        } else {
          document.getElementById("app").innerHTML = `
            <div id="sign-in"></div>
          `;

          const signInDiv = document.getElementById("sign-in");

          Clerk.mountSignIn(signInDiv);
        }
      });
    </script>
  </body>
</html>

Feedback

What did you think of this content?