useWorkspaceMemberships() hook
useWorkspaceMemberships() is the raw workspace-membership query that higher-level workspace hooks build on top of. It loads the current user’s workspace memberships with SWR and exposes the membership rows together with a manual refetch path.Usage
The following example shows a basic usage of useWorkspaceMemberships().
export default function WorkspaceMembershipList() { const { workspaceMemberships, loading } = useWorkspaceMemberships(); if (loading) { return <p>Loading memberships…</p>; } return ( <ul> {workspaceMemberships?.map((membership) => ( <li key={membership.id}>{membership.workspace.name}</li> ))} </ul> );}Return value
The hook returns the following fields and methods.
›workspaceMemberships: WorkspaceMembership[] | undefined;
workspaceMemberships: WorkspaceMembership[] | undefined;Workspace memberships for the current user.
›[].id?: string | undefined;
[].id?: string | undefined;Workspace-membership identifier.
›[].workspace?: Workspace | undefined;
[].workspace?: Workspace | undefined;Workspace attached to the membership.
›id?: string | undefined;
id?: string | undefined;Workspace identifier.
›name?: string | undefined;
name?: string | undefined;Workspace name.
›image_url?: string | undefined;
image_url?: string | undefined;Workspace image URL.
›description?: string | undefined;
description?: string | undefined;Workspace description.
›member_count?: number | undefined;
member_count?: number | undefined;Workspace member count.
›enforce_2fa?: boolean | undefined;
enforce_2fa?: boolean | undefined;Whether the workspace enforces 2FA.
›enable_ip_restriction?: boolean | undefined;
enable_ip_restriction?: boolean | undefined;Whether the workspace uses IP restrictions.
›[].organization_id?: string | undefined;
[].organization_id?: string | undefined;Parent organization identifier for the workspace membership.
›[].user_id?: string | undefined;
[].user_id?: string | undefined;User identifier attached to the membership.
›[].organization?: Organization | undefined;
[].organization?: Organization | undefined;Parent organization attached to the workspace membership.
›id?: string | undefined;
id?: string | undefined;Organization identifier.
›name?: string | undefined;
name?: string | undefined;Organization name.
›[].roles?: WorkspaceRole[] | undefined;
[].roles?: WorkspaceRole[] | undefined;Roles attached to the membership.
›[].id?: string | undefined;
[].id?: string | undefined;Role identifier.
›[].name?: string | undefined;
[].name?: string | undefined;Role name.
›[].permissions?: string[] | undefined;
[].permissions?: string[] | undefined;Permissions granted by the role.
›[].public_metadata?: Record<string, unknown> | undefined;
[].public_metadata?: Record<string, unknown> | undefined;Public metadata stored on the membership.
›[].created_at?: string | undefined;
[].created_at?: string | undefined;Creation timestamp for the membership.
›[].updated_at?: string | undefined;
[].updated_at?: string | undefined;Last update timestamp for the membership.
›[].eligibility_restriction?: { type: "none" | "ip_not_allowed" | "mfa_required" | "ip_and_mfa_required"; message: string } | undefined | undefined;
[].eligibility_restriction?: { type: "none" | "ip_not_allowed" | "mfa_required" | "ip_and_mfa_required"; message: string } | undefined | undefined;Eligibility restriction attached to the membership when one exists.
›type?: "none" | "ip_not_allowed" | "mfa_required" | "ip_and_mfa_required" | undefined;
type?: "none" | "ip_not_allowed" | "mfa_required" | "ip_and_mfa_required" | undefined;Restriction type.
›message?: string | undefined;
message?: string | undefined;Restriction message.
›loading: boolean;
loading: boolean;Whether the shared client or the workspace-memberships query is still loading.
›error: Error | undefined;
error: Error | undefined;Underlying SWR error for the workspace-memberships query.
›refetch: () => Promise<void>;
refetch: () => Promise<void>;Revalidates the workspace-memberships query.
How it works
This is the low-level membership query, not the higher-level workspace list. That is why it returns membership rows rather than plain workspaces.
Higher-level hooks such as
useWorkspaceList(), useActiveWorkspace(), and useActiveTenancy() all build on top of this membership data.The query only runs when workspaces are enabled in the current deployment. If workspace support is disabled, the hook stays on the empty/query-disabled path instead of fetching.
Because it exposes membership rows directly, this is the right hook for permission-aware workspace UI or any screen that needs role, organization, and eligibility metadata rather than only workspace names.
When to use it
Examples
Render workspace memberships
export default function WorkspaceMemberships() { const { workspaceMemberships, loading } = useWorkspaceMemberships(); if (loading) { return <p>Loading memberships…</p>; } return ( <ul> {workspaceMemberships?.map((membership) => ( <li key={membership.id}> {membership.workspace.name} ({membership.roles.length} roles) </li> ))} </ul> );}Refetch workspace memberships after an external change
export default function RefreshWorkspaceMemberships() { const { refetch } = useWorkspaceMemberships(); return <button onClick={() => refetch()}>Refresh memberships</button>;}