> ## Documentation Index
> Fetch the complete documentation index at: https://auth0-feat-member-mgmt-docs.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Manage an Organization Member on Web

> Learn how to view and manage an individual Organization member's profile and assigned roles in a two-tab layout.

export const ReleaseStageNotice = ({feature, stage, plans, contact, terms}) => {
  const stageTextMap = {
    "beta": "Beta",
    "ea": "Early Access"
  };
  const stageText = stageTextMap[stage] || "a product release stage";
  const prsLink = "/docs/troubleshoot/product-lifecycle/product-release-stages";
  const linkify = (text, url) => {
    return <a href={url} target="_blank" rel="noreferrer" class="link">{text}</a>;
  };
  const includeDetails = (plans, contact, terms) => {
    const hasDetails = terms || plans || contact;
    if (!hasDetails) return null;
    return <span data-as="p">
            {plans && <>This feature is available for {linkify(`${plans} plans`, "https://auth0.com/pricing")}. </>}
            {contact && "To participate, contact " + contact + ". "}
            {terms && <>By using this feature, you agree to the applicable Free Trial terms in Okta's {linkify("Master Subscription Agreement", "https://www.okta.com/legal")}.</>}
        </span>;
  };
  return <Warning>
            <span data-as="p">
                <strong>The {feature} feature is in {linkify(stageText, prsLink)}.</strong>
            </span>

            {includeDetails(plans, contact, terms)}
        </Warning>;
};

export const ComponentLoader = props => {
  const themePref = window?.localStorage?.getItem?.("isDarkMode");
  const theme = themePref === "dark" || themePref === "light" ? themePref : window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
  const lang = {
    i18n: {
      currentLanguage: props.lang || "en-US"
    }
  };
  return <div style={{
    minHeight: "400px",
    marginTop: "40px",
    background: theme === "light" ? "rgb(var(--gray-950)/.03)" : "rgb(255 255 255/.1)",
    display: "flex",
    alignItems: "center",
    justifyContent: "center",
    position: "relative",
    backgroundSize: "16px 16px",
    borderRadius: "10px",
    boxShadow: "0 1px 4px 0 rgba(16,30,54,0.04)",
    display: "flex",
    flexDirection: "column"
  }}>
      <div style={{
    minWidth: "320px",
    width: "96.5%",
    maxWidth: "1200px",
    margin: "12px 12px 0",
    background: theme === "light" ? "#ffffff" : "#101011",
    borderRadius: "10px",
    boxShadow: "0 2px 8px 0 rgba(16,30,54,0.04)",
    padding: "24px",
    minHeight: "400px"
  }} data-uc-component={props.componentSelector} data-uc-props={JSON.stringify(lang)}>
        <div aria-label="Loading" role="status" style={{
    position: "absolute",
    top: "50%",
    left: "50%",
    transform: "translate(-50%, -50%)",
    zIndex: 1,
    display: "flex",
    alignItems: "center",
    justifyContent: "center"
  }}>
          <svg width={40} height={40} viewBox="0 0 50 50" style={{
    display: "block"
  }}>
            <circle cx="25" cy="25" r="20" fill="none" stroke="#8A94A6" strokeWidth="5" strokeDasharray="90 150" strokeLinecap="round">
              <animateTransform attributeName="transform" type="rotate" from="0 25 25" to="360 25 25" dur="1s" repeatCount="indefinite" />
            </circle>
          </svg>
        </div>
      </div>
      <div style={{
    width: "100%",
    textAlign: "center",
    color: theme === "light" ? "#6B7280" : "ffffff",
    fontSize: "12px",
    marginTop: "8px",
    marginBottom: "8px",
    letterSpacing: "0.01em",
    fontWeight: 400
  }}>
        {props.componentPreviewText}
      </div>
    </div>;
};

<ReleaseStageNotice feature="Auth0 Universal Components" stage="beta" terms="true" contact="Auth0 Support" />

The `OrganizationMemberDetail` component gives your customers a focused view of a single Auth0 Organization member. Organization administrators can review the member's user profile, assign and remove roles, and remove the member from the Organization—all in a two-tab layout with full lifecycle controls.

This component is the per-member drill-down for the [`OrganizationMemberManagement`](/docs/get-started/universal-components/web/components/organization-member-management) component. Wire that component's `viewMemberDetailsAction` to the route that renders `OrganizationMemberDetail`; the `userId` it receives flows through to this component's required `userId` prop.

<ComponentLoader componentSelector="organization-member-detail" componentPreviewText="Preview of the Organization Member Detail component" />

<Tabs>
  <Tab title="React">
    ## Setup requirements

    <Callout icon="file-lines" color="#0EA5E9" iconType="regular">
      **Auth0 Configuration Required**—Ensure your tenant is configured with the
      My Organization API. [View setup guide
      →](/docs/get-started/universal-components/web/components/build-delegated-admin#enable-the-my-organization-api)
    </Callout>

    Removing the member and mutating roles are sensitive operations that trigger a step-up authentication challenge. Configure your `Auth0Provider` with `interactiveErrorHandler="popup"` so the challenge resolves in a popup without losing page state.

    ## Install the component

    <CodeGroup>
      ```bash pnpm  wrap lines theme={null}
      pnpm add @auth0/universal-components-react
      ```

      ```bash npm wrap lines theme={null}
      npm install @auth0/universal-components-react
      ```
    </CodeGroup>

    <Callout icon="file-lines" color="#0EA5E9" iconType="regular">
      Running either command also installs the @auth0/universal-components-core
      dependency for shared utilities and Auth0 integration.
    </Callout>

    One install covers both React (SPA) and Next.js (RWA). Components are always imported from the root entry `@auth0/universal-components-react`; only `Auth0ComponentProvider` uses a framework-specific subpath—`@auth0/universal-components-react/spa` for React.

    ## Get started

    Pass a `userId` from your route to the component. Wire `onBack` to your router so the back button returns to the member list.

    ```tsx React SPA wrap lines theme={null}
    import { OrganizationMemberDetail } from "@auth0/universal-components-react";
    import { useNavigate, useParams } from "react-router-dom";

    export function MemberDetailPage() {
      const { userId } = useParams<{ userId: string }>();
      const navigate = useNavigate();

      return (
        <OrganizationMemberDetail
          userId={userId!}
          onBack={() => navigate("/members")}
        />
      );
    }
    ```

    <Accordion title="Full integration example">
      ```tsx lines theme={null}
      import React from "react";
      import { OrganizationMemberDetail } from "@auth0/universal-components-react";
      import { Auth0Provider } from "@auth0/auth0-react";
      import { Auth0ComponentProvider } from "@auth0/universal-components-react/spa";
      import { useNavigate, useParams } from "react-router-dom";
      import { auditLog } from "./lib/audit-log";

      function MemberDetailPage() {
        const { userId } = useParams<{ userId: string }>();
        const navigate = useNavigate();

        return (
          <div className="max-w-3xl mx-auto p-6">
            <OrganizationMemberDetail
              userId={userId!}
              onBack={() => navigate("/members")}
              removeFromOrganizationAction={{
                onBefore: async () =>
                  confirm("Remove this member from the organization?"),
                onAfter: () => navigate("/members"),
              }}
              assignRolesAction={{
                onAfter: ({ userId: memberId, roleIds }) => {
                  auditLog.record({
                    action: "roles_assigned",
                    userId: memberId,
                    roleIds,
                  });
                },
              }}
              removeRolesAction={{
                onAfter: ({ userId: memberId, roleIds }) => {
                  auditLog.record({
                    action: "roles_removed",
                    userId: memberId,
                    roleIds,
                  });
                },
              }}
              customMessages={{
                member: {
                  detail: {
                    back_button: "Back to Members",
                    roles: { assign_button: "Assign Roles" },
                  },
                },
              }}
              styling={{
                variables: {
                  light: { "--color-primary": "#4f46e5" },
                  dark: { "--color-primary": "#818cf8" },
                },
              }}
            />
          </div>
        );
      }

      export default function App() {
        const domain = "YOUR_TENANT.auth0.com";
        const clientId = "YOUR_CLIENT_ID";

        return (
          <Auth0Provider
            domain={domain}
            clientId={clientId}
            authorizationParams={{ redirect_uri: window.location.origin }}
            interactiveErrorHandler="popup"
          >
            <Auth0ComponentProvider domain={domain}>
              <MemberDetailPage />
            </Auth0ComponentProvider>
          </Auth0Provider>
        );
      }
      ```
    </Accordion>

    ## Props

    ### Required props

    | Prop     | Type     | Description                                                             |
    | :------- | :------- | :---------------------------------------------------------------------- |
    | `userId` | `string` | Auth0 user ID of the member to display (for example, `auth0\|64abc...`) |

    ***

    ### Display props

    Display props control how the component renders without affecting its behavior. Use these to hide sections or enable read-only mode.

    | Prop         | Type      | Description                                                          |
    | :----------- | :-------- | :------------------------------------------------------------------- |
    | `readOnly`   | `boolean` | Disable role management and member removal actions. Default: `false` |
    | `hideHeader` | `boolean` | Hide the component header. Default: `false`                          |

    ***

    ### Action props

    Action props handle user interactions and define what happens when users perform member operations. Use lifecycle hooks (`onBefore`, `onAfter`) to integrate with your application's routing and analytics.

    | Prop                           | Type                                                     | Description                                                                          |
    | :----------------------------- | :------------------------------------------------------- | :----------------------------------------------------------------------------------- |
    | `onBack`                       | `() => void`                                             | Called when the user clicks the back button in the header. Wire this to your router. |
    | `removeFromOrganizationAction` | `ComponentAction<string>`                                | Lifecycle hooks for member removal. Input is the `userId`.                           |
    | `assignRolesAction`            | `ComponentAction<{ userId: string; roleIds: string[] }>` | Lifecycle hooks for role assignment.                                                 |
    | `removeRolesAction`            | `ComponentAction<{ userId: string; roleIds: string[] }>` | Lifecycle hooks for role removal.                                                    |

    **onBack**

    **Type:** `() => void`

    Fires when the user clicks the back button in the header. The component does not navigate on its own—wire this callback to your router so it returns to the member-list route, typically the page that renders [`OrganizationMemberManagement`](/docs/get-started/universal-components/web/components/organization-member-management).

    **Example:**

    ```tsx wrap lines theme={null}
    // Navigate to a fixed route
    <OrganizationMemberDetail userId={userId} onBack={() => navigate("/members")} />

    // Or pop the history stack instead
    <OrganizationMemberDetail userId={userId} onBack={() => history.back()} />
    ```

    ***

    **removeFromOrganizationAction**

    **Type:** `ComponentAction<string>`

    Controls the remove-from-organization flow on the member's profile tab. Both lifecycle hooks receive the `userId` string directly.

    <Callout icon="file-lines" color="#0EA5E9" iconType="regular">
      This action triggers a step-up authentication challenge. Configure your
      `Auth0Provider` with `interactiveErrorHandler="popup"`.
    </Callout>

    **Properties:**

    * `disabled`—Hide the remove button.
    * `onBefore(userId)`—Runs before the member is removed. Return `false` to cancel.
    * `onAfter(userId)`—Runs after the member is removed. Use this to navigate away or write to an audit log.

    **Example:**

    ```tsx wrap lines theme={null}
    <OrganizationMemberDetail
      userId={userId}
      removeFromOrganizationAction={{
        onBefore: async () => confirm("Remove this member from the organization?"),
        onAfter: (removedUserId) => {
          auditLog.record({ action: "member_removed", userId: removedUserId });
          navigate("/members");
        },
      }}
    />
    ```

    ***

    **assignRolesAction**

    **Type:** `ComponentAction<{ userId: string; roleIds: string[] }>`

    Fires after one or more roles are assigned to the member from the roles tab. Both lifecycle hooks receive an object with the `userId` and the array of `roleIds` being assigned.

    **Properties:**

    * `disabled`—Hide the assign-roles button.
    * `onBefore({ userId, roleIds })`—Validate the selection. Return `false` to cancel.
    * `onAfter({ userId, roleIds })`—Runs after the roles are assigned.

    **Example:**

    ```tsx wrap lines theme={null}
    <OrganizationMemberDetail
      userId={userId}
      assignRolesAction={{
        onAfter: ({ userId: memberId, roleIds }) => {
          auditLog.record({
            action: "roles_assigned",
            userId: memberId,
            roleIds,
          });
          analytics.track("Roles Assigned", { count: roleIds.length });
        },
      }}
    />
    ```

    ***

    **removeRolesAction**

    **Type:** `ComponentAction<{ userId: string; roleIds: string[] }>`

    Fires after one or more roles are removed from the member's role table. Both lifecycle hooks receive an object with the `userId` and the array of `roleIds` being removed.

    **Properties:**

    * `disabled`—Hide the remove-role buttons in the role table.
    * `onBefore({ userId, roleIds })`—Runs before the roles are removed. Return `false` to cancel.
    * `onAfter({ userId, roleIds })`—Runs after the roles are removed.

    **Example:**

    ```tsx wrap lines theme={null}
    <OrganizationMemberDetail
      userId={userId}
      removeRolesAction={{
        onBefore: async ({ roleIds }) =>
          confirm(`Remove ${roleIds.length} role(s) from this member?`),
        onAfter: ({ userId: memberId, roleIds }) => {
          auditLog.record({ action: "roles_removed", userId: memberId, roleIds });
        },
      }}
    />
    ```

    ***

    ### Customization props

    Customization props let you override default text and apply CSS variables or class names to match your application's design system.

    | Prop             | Type                                        | Description                                                                  |
    | :--------------- | :------------------------------------------ | :--------------------------------------------------------------------------- |
    | `customMessages` | `Partial<OrganizationMemberDetailMessages>` | Override any default UI text or translations. Default: `{}`                  |
    | `styling`        | `ComponentStyling`                          | CSS variables and class overrides. Default: `{ variables: {}, classes: {} }` |

    **customMessages**

    Customize all text and translations rendered by the component. Every field is optional and falls back to the built-in default. Use this prop to localize the component or to align microcopy with your product voice.

    <Accordion title="Available Messages">
      **member.detail**—Header and tabs

      * `back_button`
      * `tabs.details`, `tabs.roles`

      **member.detail.user\_details**—Profile card

      * `title`
      * `name`, `email`
      * `created_at`, `last_login`

      **member.detail.actions.remove\_from\_organization**—Remove member

      * `title`, `description`, `button`
      * `modal.title`, `modal.description`
      * `modal.cancel_button`, `modal.confirm_button`
      * `success`

      **member.detail.roles**—Roles tab

      * `title`, `description`
      * `assign_button`
      * `table.name`, `table.description`
      * `table.empty_message`
      * `table.remove_button_label`

      **member.detail.roles.assign\_modal**—Assign roles modal

      * `title`, `description`
      * `roles_label`, `roles_placeholder`
      * `submit_button`, `cancel_button`
      * `no_roles_available`

      **member.detail.error**—API responses

      * `fetch_failed`, `fetch_roles_failed`
      * `remove_from_organization_failed`
      * `assign_role_failed`, `remove_role_failed`
    </Accordion>

    ```tsx wrap lines theme={null}
    <OrganizationMemberDetail
      userId={userId}
      customMessages={{
        member: {
          detail: {
            back_button: "Back to Members",
            tabs: { details: "Profile", roles: "Permissions" },
            roles: {
              assign_button: "Add Permission",
              table: { empty_message: "No permissions assigned yet." },
            },
            actions: {
              remove_from_organization: {
                title: "Remove from Organization",
                button: "Remove",
                modal: {
                  title: "Remove Member",
                  confirm_button: "Yes, Remove",
                },
              },
            },
          },
        },
      }}
    />
    ```

    ***

    **styling**

    Customize appearance with CSS variables and class overrides. Variables are theme-aware (separate `light`, `dark`, and `common` scopes); class overrides target named slots inside the component tree so you can attach utility or design-system classes without forking the source.

    <Accordion title="Available Styling Options">
      **Variables**—CSS custom properties

      * `common`—Applied to all themes
      * `light`—Light theme only
      * `dark`—Dark theme only

      **Classes**—Component class overrides

      * `OrganizationMemberDetail-root`
      * `OrganizationMemberDetail-header`
      * `OrganizationMemberDetail-tabs`
      * `OrganizationMemberDetail-detailsTab`
      * `OrganizationMemberDetail-rolesTab`
      * `MemberRemoveFromOrgModal-dialogContent`
      * `OrganizationMemberRemoveRoleModal-dialogContent`
      * `OrganizationMemberAssignRolesModal-dialogContent`
    </Accordion>

    ```tsx wrap lines theme={null}
    <OrganizationMemberDetail
      userId={userId}
      styling={{
        variables: {
          light: { "--color-primary": "#4f46e5" },
          dark: { "--color-primary": "#818cf8" },
        },
        classes: {
          "OrganizationMemberDetail-root": "max-w-3xl mx-auto",
          "OrganizationMemberDetail-header": "mb-6",
          "OrganizationMemberDetail-rolesTab": "mt-4",
        },
      }}
    />
    ```

    ***

    ## Advanced customization

    The `OrganizationMemberDetail` component is composed of smaller subcomponents and hooks. Import them individually to build custom workflows.

    ### Available subcomponents

    | Subcomponent                         | Description                                                                |
    | :----------------------------------- | :------------------------------------------------------------------------- |
    | `OrganizationMemberEditDetailsTab`   | User profile card plus the remove-from-organization danger zone            |
    | `OrganizationMemberEditRolesTab`     | Role table with assign and remove controls                                 |
    | `OrganizationMemberAssignRolesModal` | Role selector modal                                                        |
    | `OrganizationMemberRemoveRoleModal`  | Single-role removal confirmation                                           |
    | `MemberRemoveFromOrgModal`           | Member removal confirmation modal                                          |
    | `OrganizationMemberDetailView`       | Stateless view layer—bring your own data via `useOrganizationMemberDetail` |

    ### Available hooks

    These hooks provide the underlying logic without any UI. Use them to build completely custom interfaces while leveraging the Auth0 API integration.

    | Hook                          | Description                                                                               |
    | :---------------------------- | :---------------------------------------------------------------------------------------- |
    | `useOrganizationMemberDetail` | Data + interaction layer: member query, role queries, modal state, and all event handlers |
  </Tab>

  <Tab title="Next.js">
    ## Setup requirements

    <Callout icon="file-lines" color="#0EA5E9" iconType="regular">
      **Auth0 Configuration Required**—Ensure your tenant is configured with the
      My Organization API. [View setup guide
      →](/docs/get-started/universal-components/web/components/build-delegated-admin#configure-auth0-dashboard)
    </Callout>

    Removing the member and mutating roles are sensitive operations that trigger a step-up authentication challenge. Configure your Auth0 SDK with `interactiveErrorHandler="popup"` so the challenge resolves in a popup without losing page state.

    ## Install component

    <CodeGroup>
      ```bash npm  wrap lines theme={null}
      npm install @auth0/universal-components-react
      ```

      ```bash pnpm wrap lines theme={null}
      pnpm add @auth0/universal-components-react
      ```
    </CodeGroup>

    <Callout icon="file-lines" color="#0EA5E9" iconType="regular">
      Running the pnpm or npm commands installs the @auth0/universal-components-core
      dependency for shared utilities and Auth0 integration.
    </Callout>

    One install covers both React (SPA) and Next.js (RWA). Components are always imported from the root entry `@auth0/universal-components-react`; only `Auth0ComponentProvider` uses a framework-specific subpath—`@auth0/universal-components-react/rwa` for Next.js.

    ## Get started

    Pass a `userId` from your dynamic route segment to the component. Wire `onBack` to your router so the back button returns to the member list.

    ```tsx page.tsx wrap lines theme={null}
    // app/members/[userId]/page.tsx
    "use client";

    import { OrganizationMemberDetail } from "@auth0/universal-components-react";
    import { useRouter, useParams } from "next/navigation";

    export default function MemberDetailPage() {
      const { userId } = useParams<{ userId: string }>();
      const router = useRouter();

      return (
        <OrganizationMemberDetail
          userId={userId}
          onBack={() => router.push("/members")}
        />
      );
    }
    ```

    <Accordion title="Full integration example">
      ```tsx lines theme={null}
      // app/members/[userId]/page.tsx
      "use client";

      import React from "react";
      import { OrganizationMemberDetail } from "@auth0/universal-components-react";
      import { useRouter, useParams } from "next/navigation";
      import { auditLog } from "@/lib/audit-log";

      export default function MemberDetailPage() {
        const { userId } = useParams<{ userId: string }>();
        const router = useRouter();

        return (
          <div className="max-w-3xl mx-auto p-6">
            <OrganizationMemberDetail
              userId={userId}
              onBack={() => router.push("/members")}
              removeFromOrganizationAction={{
                onBefore: async () =>
                  confirm("Remove this member from the organization?"),
                onAfter: () => router.push("/members"),
              }}
              assignRolesAction={{
                onAfter: ({ userId: memberId, roleIds }) => {
                  auditLog.record({
                    action: "roles_assigned",
                    userId: memberId,
                    roleIds,
                  });
                },
              }}
              removeRolesAction={{
                onAfter: ({ userId: memberId, roleIds }) => {
                  auditLog.record({
                    action: "roles_removed",
                    userId: memberId,
                    roleIds,
                  });
                },
              }}
              customMessages={{
                member: {
                  detail: {
                    back_button: "Back to Members",
                    roles: { assign_button: "Assign Roles" },
                  },
                },
              }}
              styling={{
                variables: {
                  light: { "--color-primary": "#4f46e5" },
                  dark: { "--color-primary": "#818cf8" },
                },
              }}
            />
          </div>
        );
      }
      ```

      Wrap your application with the RWA provider in the root layout:

      ```tsx layout.tsx lines theme={null}
      // app/layout.tsx
      import { Auth0ComponentProvider } from "@auth0/universal-components-react/rwa";

      export default function RootLayout({
        children,
      }: {
        children: React.ReactNode;
      }) {
        return (
          <html lang="en">
            <body>
              <Auth0ComponentProvider domain="YOUR_TENANT.auth0.com">
                {children}
              </Auth0ComponentProvider>
            </body>
          </html>
        );
      }
      ```
    </Accordion>

    ## Props

    ### Required props

    | Prop     | Type     | Description                                                             |
    | :------- | :------- | :---------------------------------------------------------------------- |
    | `userId` | `string` | Auth0 user ID of the member to display (for example, `auth0\|64abc...`) |

    ***

    ### Display props

    Display props control how the component renders without affecting its behavior. Use these to hide sections or enable read-only mode.

    | Prop         | Type      | Description                                                          |
    | :----------- | :-------- | :------------------------------------------------------------------- |
    | `readOnly`   | `boolean` | Disable role management and member removal actions. Default: `false` |
    | `hideHeader` | `boolean` | Hide the component header. Default: `false`                          |

    ***

    ### Action props

    Action props handle user interactions and define what happens when users perform member operations. Use lifecycle hooks (`onBefore`, `onAfter`) to integrate with your application's routing and analytics.

    | Prop                           | Type                                                     | Description                                                                          |
    | :----------------------------- | :------------------------------------------------------- | :----------------------------------------------------------------------------------- |
    | `onBack`                       | `() => void`                                             | Called when the user clicks the back button in the header. Wire this to your router. |
    | `removeFromOrganizationAction` | `ComponentAction<string>`                                | Lifecycle hooks for member removal. Input is the `userId`.                           |
    | `assignRolesAction`            | `ComponentAction<{ userId: string; roleIds: string[] }>` | Lifecycle hooks for role assignment.                                                 |
    | `removeRolesAction`            | `ComponentAction<{ userId: string; roleIds: string[] }>` | Lifecycle hooks for role removal.                                                    |

    **onBack**

    **Type:** `() => void`

    Fires when the user clicks the back button in the header. The component does not navigate on its own—wire this callback to your router so it returns to the member-list route, typically the page that renders [`OrganizationMemberManagement`](/docs/get-started/universal-components/web/components/organization-member-management).

    **Example:**

    ```tsx wrap lines theme={null}
    // Navigate to a fixed route
    <OrganizationMemberDetail
      userId={userId}
      onBack={() => router.push("/members")}
    />

    // Or pop the history stack instead
    <OrganizationMemberDetail userId={userId} onBack={() => router.back()} />
    ```

    ***

    **removeFromOrganizationAction**

    **Type:** `ComponentAction<string>`

    Controls the remove-from-organization flow on the member's profile tab. Both lifecycle hooks receive the `userId` string directly.

    <Callout icon="file-lines" color="#0EA5E9" iconType="regular">
      This action triggers a step-up authentication challenge. Configure your Auth0
      SDK with `interactiveErrorHandler="popup"`.
    </Callout>

    **Properties:**

    * `disabled`—Hide the remove button.
    * `onBefore(userId)`—Runs before the member is removed. Return `false` to cancel.
    * `onAfter(userId)`—Runs after the member is removed. Use this to navigate away or write to an audit log.

    **Example:**

    ```tsx wrap lines theme={null}
    <OrganizationMemberDetail
      userId={userId}
      removeFromOrganizationAction={{
        onBefore: async () => confirm("Remove this member from the organization?"),
        onAfter: (removedUserId) => {
          auditLog.record({ action: "member_removed", userId: removedUserId });
          router.push("/members");
        },
      }}
    />
    ```

    ***

    **assignRolesAction**

    **Type:** `ComponentAction<{ userId: string; roleIds: string[] }>`

    Fires after one or more roles are assigned to the member from the roles tab. Both lifecycle hooks receive an object with the `userId` and the array of `roleIds` being assigned.

    **Properties:**

    * `disabled`—Hide the assign-roles button.
    * `onBefore({ userId, roleIds })`—Validate the selection. Return `false` to cancel.
    * `onAfter({ userId, roleIds })`—Runs after the roles are assigned.

    **Example:**

    ```tsx wrap lines theme={null}
    <OrganizationMemberDetail
      userId={userId}
      assignRolesAction={{
        onAfter: ({ userId: memberId, roleIds }) => {
          auditLog.record({
            action: "roles_assigned",
            userId: memberId,
            roleIds,
          });
          analytics.track("Roles Assigned", { count: roleIds.length });
        },
      }}
    />
    ```

    ***

    **removeRolesAction**

    **Type:** `ComponentAction<{ userId: string; roleIds: string[] }>`

    Fires after one or more roles are removed from the member's role table. Both lifecycle hooks receive an object with the `userId` and the array of `roleIds` being removed.

    **Properties:**

    * `disabled`—Hide the remove-role buttons in the role table.
    * `onBefore({ userId, roleIds })`—Runs before the roles are removed. Return `false` to cancel.
    * `onAfter({ userId, roleIds })`—Runs after the roles are removed.

    **Example:**

    ```tsx wrap lines theme={null}
    <OrganizationMemberDetail
      userId={userId}
      removeRolesAction={{
        onBefore: async ({ roleIds }) =>
          confirm(`Remove ${roleIds.length} role(s) from this member?`),
        onAfter: ({ userId: memberId, roleIds }) => {
          auditLog.record({ action: "roles_removed", userId: memberId, roleIds });
        },
      }}
    />
    ```

    ***

    ### Customization props

    Customization props let you override default text and apply CSS variables or class names to match your application's design system.

    | Prop             | Type                                        | Description                                                                  |
    | :--------------- | :------------------------------------------ | :--------------------------------------------------------------------------- |
    | `customMessages` | `Partial<OrganizationMemberDetailMessages>` | Override any default UI text or translations. Default: `{}`                  |
    | `styling`        | `ComponentStyling`                          | CSS variables and class overrides. Default: `{ variables: {}, classes: {} }` |

    **customMessages**

    Customize all text and translations rendered by the component. Every field is optional and falls back to the built-in default. Use this prop to localize the component or to align microcopy with your product voice.

    <Accordion title="Available Messages">
      **member.detail**—Header and tabs

      * `back_button`
      * `tabs.details`, `tabs.roles`

      **member.detail.user\_details**—Profile card

      * `title`
      * `name`, `email`
      * `created_at`, `last_login`

      **member.detail.actions.remove\_from\_organization**—Remove member

      * `title`, `description`, `button`
      * `modal.title`, `modal.description`
      * `modal.cancel_button`, `modal.confirm_button`
      * `success`

      **member.detail.roles**—Roles tab

      * `title`, `description`
      * `assign_button`
      * `table.name`, `table.description`
      * `table.empty_message`
      * `table.remove_button_label`

      **member.detail.roles.assign\_modal**—Assign roles modal

      * `title`, `description`
      * `roles_label`, `roles_placeholder`
      * `submit_button`, `cancel_button`
      * `no_roles_available`

      **member.detail.error**—API responses

      * `fetch_failed`, `fetch_roles_failed`
      * `remove_from_organization_failed`
      * `assign_role_failed`, `remove_role_failed`
    </Accordion>

    ```tsx wrap lines theme={null}
    <OrganizationMemberDetail
      userId={userId}
      customMessages={{
        member: {
          detail: {
            back_button: "Back to Members",
            tabs: { details: "Profile", roles: "Permissions" },
            roles: {
              assign_button: "Add Permission",
              table: { empty_message: "No permissions assigned yet." },
            },
            actions: {
              remove_from_organization: {
                title: "Remove from Organization",
                button: "Remove",
                modal: {
                  title: "Remove Member",
                  confirm_button: "Yes, Remove",
                },
              },
            },
          },
        },
      }}
    />
    ```

    ***

    **styling**

    Customize appearance with CSS variables and class overrides. Variables are theme-aware (separate `light`, `dark`, and `common` scopes); class overrides target named slots inside the component tree so you can attach utility or design-system classes without forking the source.

    <Accordion title="Available Styling Options">
      **Variables**—CSS custom properties

      * `common`—Applied to all themes
      * `light`—Light theme only
      * `dark`—Dark theme only

      **Classes**—Component class overrides

      * `OrganizationMemberDetail-root`
      * `OrganizationMemberDetail-header`
      * `OrganizationMemberDetail-tabs`
      * `OrganizationMemberDetail-detailsTab`
      * `OrganizationMemberDetail-rolesTab`
      * `MemberRemoveFromOrgModal-dialogContent`
      * `OrganizationMemberRemoveRoleModal-dialogContent`
      * `OrganizationMemberAssignRolesModal-dialogContent`
    </Accordion>

    ```tsx wrap lines theme={null}
    <OrganizationMemberDetail
      userId={userId}
      styling={{
        variables: {
          light: { "--color-primary": "#4f46e5" },
          dark: { "--color-primary": "#818cf8" },
        },
        classes: {
          "OrganizationMemberDetail-root": "max-w-3xl mx-auto",
          "OrganizationMemberDetail-header": "mb-6",
          "OrganizationMemberDetail-rolesTab": "mt-4",
        },
      }}
    />
    ```

    ***

    ## Advanced customization

    The `OrganizationMemberDetail` component is composed of smaller subcomponents and hooks. Import them individually to build custom workflows.

    ### Available subcomponents

    | Subcomponent                         | Description                                                                |
    | :----------------------------------- | :------------------------------------------------------------------------- |
    | `OrganizationMemberEditDetailsTab`   | User profile card plus the remove-from-organization danger zone            |
    | `OrganizationMemberEditRolesTab`     | Role table with assign and remove controls                                 |
    | `OrganizationMemberAssignRolesModal` | Role selector modal                                                        |
    | `OrganizationMemberRemoveRoleModal`  | Single-role removal confirmation                                           |
    | `MemberRemoveFromOrgModal`           | Member removal confirmation modal                                          |
    | `OrganizationMemberDetailView`       | Stateless view layer—bring your own data via `useOrganizationMemberDetail` |

    ### Available hooks

    These hooks provide the underlying logic without any UI. Use them to build completely custom interfaces while leveraging the Auth0 API integration.

    | Hook                          | Description                                                                               |
    | :---------------------------- | :---------------------------------------------------------------------------------------- |
    | `useOrganizationMemberDetail` | Data + interaction layer: member query, role queries, modal state, and all event handlers |
  </Tab>

  <Tab title="shadcn">
    ## Setup requirements

    <Callout icon="file-lines" color="#0EA5E9" iconType="regular">
      **Auth0 Configuration Required**—Ensure your tenant is configured with the
      My Organization API. [View setup guide
      →](/docs/get-started/universal-components/web/components/build-delegated-admin#configure-auth0-dashboard)
    </Callout>

    Removing the member and mutating roles are sensitive operations that trigger a step-up authentication challenge. Configure your `Auth0Provider` with `interactiveErrorHandler="popup"` so the challenge resolves in a popup without losing page state.

    ## Install the component

    Install the component via the shadcn CLI using the GitHub Registry:

    ```bash wrap lines theme={null}
    npx shadcn@latest add auth0/auth0-ui-components/react/my-organization/organization-member-detail
    ```

    <Callout icon="file-lines" color="#0EA5E9" iconType="regular">
      The shadcn CLI also installs the `@auth0/universal-components-core`
      dependency for shared utilities and Auth0 integration.
      Requires **shadcn CLI v2.5.0+**.
    </Callout>

    <details>
      <summary>Legacy Vercel registry (deprecated)</summary>

      Existing consumers can continue using the Vercel-hosted path until **September 17, 2026**:

      ```bash wrap lines theme={null}
      npx shadcn@latest add https://auth0-universal-components.vercel.app/r/my-organization/organization-member-detail.json
      ```

      New projects should use the GitHub Registry path above.
    </details>

    The CLI installs the React component source code in your `src/components/auth0/` directory along with all UI dependencies and the core package.

    ## Get started

    Pass a `userId` from your route to the component. Wire `onBack` to your router so the back button returns to the member list.

    ```tsx wrap lines theme={null}
    import { OrganizationMemberDetail } from "@/components/auth0/my-organization/organization-member-detail";
    import { useNavigate, useParams } from "react-router-dom";

    export function MemberDetailPage() {
      const { userId } = useParams<{ userId: string }>();
      const navigate = useNavigate();

      return (
        <OrganizationMemberDetail
          userId={userId!}
          onBack={() => navigate("/members")}
        />
      );
    }
    ```

    <Accordion title="Full integration example">
      ```tsx lines theme={null}
      import React from "react";
      import { OrganizationMemberDetail } from "@/components/auth0/my-organization/organization-member-detail";
      import { Auth0Provider } from "@auth0/auth0-react";
      import { Auth0ComponentProvider } from "@auth0/universal-components-react/spa";
      import { useNavigate, useParams } from "react-router-dom";
      import { auditLog } from "./lib/audit-log";

      function MemberDetailPage() {
        const { userId } = useParams<{ userId: string }>();
        const navigate = useNavigate();

        return (
          <div className="max-w-3xl mx-auto p-6">
            <OrganizationMemberDetail
              userId={userId!}
              onBack={() => navigate("/members")}
              removeFromOrganizationAction={{
                onBefore: async () =>
                  confirm("Remove this member from the organization?"),
                onAfter: () => navigate("/members"),
              }}
              assignRolesAction={{
                onAfter: ({ userId: memberId, roleIds }) => {
                  auditLog.record({
                    action: "roles_assigned",
                    userId: memberId,
                    roleIds,
                  });
                },
              }}
              removeRolesAction={{
                onAfter: ({ userId: memberId, roleIds }) => {
                  auditLog.record({
                    action: "roles_removed",
                    userId: memberId,
                    roleIds,
                  });
                },
              }}
              customMessages={{
                member: {
                  detail: {
                    back_button: "Back to Members",
                    roles: { assign_button: "Assign Roles" },
                  },
                },
              }}
              styling={{
                variables: {
                  light: { "--color-primary": "#4f46e5" },
                  dark: { "--color-primary": "#818cf8" },
                },
              }}
            />
          </div>
        );
      }

      export default function App() {
        const domain = "YOUR_TENANT.auth0.com";
        const clientId = "YOUR_CLIENT_ID";

        return (
          <Auth0Provider
            domain={domain}
            clientId={clientId}
            authorizationParams={{ redirect_uri: window.location.origin }}
            interactiveErrorHandler="popup"
          >
            <Auth0ComponentProvider domain={domain}>
              <MemberDetailPage />
            </Auth0ComponentProvider>
          </Auth0Provider>
        );
      }
      ```
    </Accordion>

    ## Props

    ### Required props

    | Prop     | Type     | Description                                                             |
    | :------- | :------- | :---------------------------------------------------------------------- |
    | `userId` | `string` | Auth0 user ID of the member to display (for example, `auth0\|64abc...`) |

    ***

    ### Display props

    Display props control how the component renders without affecting its behavior. Use these to hide sections or enable read-only mode.

    | Prop         | Type      | Description                                                          |
    | :----------- | :-------- | :------------------------------------------------------------------- |
    | `readOnly`   | `boolean` | Disable role management and member removal actions. Default: `false` |
    | `hideHeader` | `boolean` | Hide the component header. Default: `false`                          |

    ***

    ### Action props

    Action props handle user interactions and define what happens when users perform member operations. Use lifecycle hooks (`onBefore`, `onAfter`) to integrate with your application's routing and analytics.

    | Prop                           | Type                                                     | Description                                                                          |
    | :----------------------------- | :------------------------------------------------------- | :----------------------------------------------------------------------------------- |
    | `onBack`                       | `() => void`                                             | Called when the user clicks the back button in the header. Wire this to your router. |
    | `removeFromOrganizationAction` | `ComponentAction<string>`                                | Lifecycle hooks for member removal. Input is the `userId`.                           |
    | `assignRolesAction`            | `ComponentAction<{ userId: string; roleIds: string[] }>` | Lifecycle hooks for role assignment.                                                 |
    | `removeRolesAction`            | `ComponentAction<{ userId: string; roleIds: string[] }>` | Lifecycle hooks for role removal.                                                    |

    **onBack**

    **Type:** `() => void`

    Fires when the user clicks the back button in the header. The component does not navigate on its own—wire this callback to your router so it returns to the member-list route, typically the page that renders [`OrganizationMemberManagement`](/docs/get-started/universal-components/web/components/organization-member-management).

    **Example:**

    ```tsx wrap lines theme={null}
    // Navigate to a fixed route
    <OrganizationMemberDetail userId={userId} onBack={() => navigate("/members")} />

    // Or pop the history stack instead
    <OrganizationMemberDetail userId={userId} onBack={() => history.back()} />
    ```

    ***

    **removeFromOrganizationAction**

    **Type:** `ComponentAction<string>`

    Controls the remove-from-organization flow on the member's profile tab. Both lifecycle hooks receive the `userId` string directly.

    <Callout icon="file-lines" color="#0EA5E9" iconType="regular">
      This action triggers a step-up authentication challenge. Configure your
      `Auth0Provider` with `interactiveErrorHandler="popup"`.
    </Callout>

    **Properties:**

    * `disabled`—Hide the remove button.
    * `onBefore(userId)`—Runs before the member is removed. Return `false` to cancel.
    * `onAfter(userId)`—Runs after the member is removed. Use this to navigate away or write to an audit log.

    **Example:**

    ```tsx wrap lines theme={null}
    <OrganizationMemberDetail
      userId={userId}
      removeFromOrganizationAction={{
        onBefore: async () => confirm("Remove this member from the organization?"),
        onAfter: (removedUserId) => {
          auditLog.record({ action: "member_removed", userId: removedUserId });
          navigate("/members");
        },
      }}
    />
    ```

    ***

    **assignRolesAction**

    **Type:** `ComponentAction<{ userId: string; roleIds: string[] }>`

    Fires after one or more roles are assigned to the member from the roles tab. Both lifecycle hooks receive an object with the `userId` and the array of `roleIds` being assigned.

    **Properties:**

    * `disabled`—Hide the assign-roles button.
    * `onBefore({ userId, roleIds })`—Validate the selection. Return `false` to cancel.
    * `onAfter({ userId, roleIds })`—Runs after the roles are assigned.

    **Example:**

    ```tsx wrap lines theme={null}
    <OrganizationMemberDetail
      userId={userId}
      assignRolesAction={{
        onAfter: ({ userId: memberId, roleIds }) => {
          auditLog.record({
            action: "roles_assigned",
            userId: memberId,
            roleIds,
          });
          analytics.track("Roles Assigned", { count: roleIds.length });
        },
      }}
    />
    ```

    ***

    **removeRolesAction**

    **Type:** `ComponentAction<{ userId: string; roleIds: string[] }>`

    Fires after one or more roles are removed from the member's role table. Both lifecycle hooks receive an object with the `userId` and the array of `roleIds` being removed.

    **Properties:**

    * `disabled`—Hide the remove-role buttons in the role table.
    * `onBefore({ userId, roleIds })`—Runs before the roles are removed. Return `false` to cancel.
    * `onAfter({ userId, roleIds })`—Runs after the roles are removed.

    **Example:**

    ```tsx wrap lines theme={null}
    <OrganizationMemberDetail
      userId={userId}
      removeRolesAction={{
        onBefore: async ({ roleIds }) =>
          confirm(`Remove ${roleIds.length} role(s) from this member?`),
        onAfter: ({ userId: memberId, roleIds }) => {
          auditLog.record({ action: "roles_removed", userId: memberId, roleIds });
        },
      }}
    />
    ```

    ***

    ### Customization props

    Customization props let you override default text and apply CSS variables or class names to match your application's design system.

    | Prop             | Type                                        | Description                                                                  |
    | :--------------- | :------------------------------------------ | :--------------------------------------------------------------------------- |
    | `customMessages` | `Partial<OrganizationMemberDetailMessages>` | Override any default UI text or translations. Default: `{}`                  |
    | `styling`        | `ComponentStyling`                          | CSS variables and class overrides. Default: `{ variables: {}, classes: {} }` |

    **customMessages**

    Customize all text and translations rendered by the component. Every field is optional and falls back to the built-in default. Use this prop to localize the component or to align microcopy with your product voice.

    <Accordion title="Available Messages">
      **member.detail**—Header and tabs

      * `back_button`
      * `tabs.details`, `tabs.roles`

      **member.detail.user\_details**—Profile card

      * `title`
      * `name`, `email`
      * `created_at`, `last_login`

      **member.detail.actions.remove\_from\_organization**—Remove member

      * `title`, `description`, `button`
      * `modal.title`, `modal.description`
      * `modal.cancel_button`, `modal.confirm_button`
      * `success`

      **member.detail.roles**—Roles tab

      * `title`, `description`
      * `assign_button`
      * `table.name`, `table.description`
      * `table.empty_message`
      * `table.remove_button_label`

      **member.detail.roles.assign\_modal**—Assign roles modal

      * `title`, `description`
      * `roles_label`, `roles_placeholder`
      * `submit_button`, `cancel_button`
      * `no_roles_available`

      **member.detail.error**—API responses

      * `fetch_failed`, `fetch_roles_failed`
      * `remove_from_organization_failed`
      * `assign_role_failed`, `remove_role_failed`
    </Accordion>

    ```tsx wrap lines theme={null}
    <OrganizationMemberDetail
      userId={userId}
      customMessages={{
        member: {
          detail: {
            back_button: "Back to Members",
            tabs: { details: "Profile", roles: "Permissions" },
            roles: {
              assign_button: "Add Permission",
              table: { empty_message: "No permissions assigned yet." },
            },
            actions: {
              remove_from_organization: {
                title: "Remove from Organization",
                button: "Remove",
                modal: {
                  title: "Remove Member",
                  confirm_button: "Yes, Remove",
                },
              },
            },
          },
        },
      }}
    />
    ```

    ***

    **styling**

    Customize appearance with CSS variables and class overrides. Variables are theme-aware (separate `light`, `dark`, and `common` scopes); class overrides target named slots inside the component tree so you can attach utility or design-system classes without forking the source.

    <Accordion title="Available Styling Options">
      **Variables**—CSS custom properties

      * `common`—Applied to all themes
      * `light`—Light theme only
      * `dark`—Dark theme only

      **Classes**—Component class overrides

      * `OrganizationMemberDetail-root`
      * `OrganizationMemberDetail-header`
      * `OrganizationMemberDetail-tabs`
      * `OrganizationMemberDetail-detailsTab`
      * `OrganizationMemberDetail-rolesTab`
      * `MemberRemoveFromOrgModal-dialogContent`
      * `OrganizationMemberRemoveRoleModal-dialogContent`
      * `OrganizationMemberAssignRolesModal-dialogContent`
    </Accordion>

    ```tsx wrap lines theme={null}
    <OrganizationMemberDetail
      userId={userId}
      styling={{
        variables: {
          light: { "--color-primary": "#4f46e5" },
          dark: { "--color-primary": "#818cf8" },
        },
        classes: {
          "OrganizationMemberDetail-root": "max-w-3xl mx-auto",
          "OrganizationMemberDetail-header": "mb-6",
          "OrganizationMemberDetail-rolesTab": "mt-4",
        },
      }}
    />
    ```

    ***

    ## Advanced customization

    The `OrganizationMemberDetail` component is composed of smaller subcomponents and hooks. Because the shadcn CLI installs the source into your project, you can import them individually to build custom workflows.

    ### Available subcomponents

    | Subcomponent                         | Description                                                                |
    | :----------------------------------- | :------------------------------------------------------------------------- |
    | `OrganizationMemberEditDetailsTab`   | User profile card plus the remove-from-organization danger zone            |
    | `OrganizationMemberEditRolesTab`     | Role table with assign and remove controls                                 |
    | `OrganizationMemberAssignRolesModal` | Role selector modal                                                        |
    | `OrganizationMemberRemoveRoleModal`  | Single-role removal confirmation                                           |
    | `MemberRemoveFromOrgModal`           | Member removal confirmation modal                                          |
    | `OrganizationMemberDetailView`       | Stateless view layer—bring your own data via `useOrganizationMemberDetail` |

    ### Available hooks

    These hooks provide the underlying logic without any UI. Use them to build completely custom interfaces while leveraging the Auth0 API integration.

    | Hook                          | Description                                                                               |
    | :---------------------------- | :---------------------------------------------------------------------------------------- |
    | `useOrganizationMemberDetail` | Data + interaction layer: member query, role queries, modal state, and all event handlers |
  </Tab>
</Tabs>
