šŸ“ Sign Up | šŸ” Log In

← Root | ↑ Up

ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” │ šŸ“„ shadcn/directory/clerk/clerk-docs/reference/hooks/use-organization-list │ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜

╔══════════════════════════════════════════════════════════════════════════════════════════════╗
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘

title: 'useOrganizationList()' description: Access and manage the current user's organization list in your React application with Clerk's useOrganizationList() hook. sdk: chrome-extension, expo, nextjs, react, react-router, remix, tanstack-react-start

The useOrganizationList() hook provides access to the current user's organization memberships, invitations, and suggestions. It also includes methods for creating new organizations and managing the active organization.

Examples

Expanding and paginating attributes

To keep network usage to a minimum, developers are required to opt-in by specifying which resource they need to fetch and paginate through. So by default, the userMemberships, userInvitations, and userSuggestions attributes are not populated. You must pass true or an object with the desired properties to fetch and paginate the data.

// userMemberships.data will never be populated
const { userMemberships } = useOrganizationList()

// Use default values to fetch userMemberships, such as initialPage = 1 and pageSize = 10
const { userMemberships } = useOrganizationList({
  userMemberships: true,
})

// Pass your own values to fetch userMemberships
const { userMemberships } = useOrganizationList({
  userMemberships: {
    pageSize: 20,
    initialPage: 2, // skips the first page
  },
})

// Aggregate pages in order to render an infinite list
const { userMemberships } = useOrganizationList({
  userMemberships: {
    infinite: true,
  },
})

Infinite pagination

The following example demonstrates how to use the infinite property to fetch and append new data to the existing list. The userMemberships attribute will be populated with the first page of the user's organization memberships. When the "Load more" button is clicked, the fetchNext helper function will be called to append the next page of memberships to the list.

<If sdk="react"> ```tsx {{ filename: 'src/components/JoinedOrganizations.tsx' }} import { useOrganizationList } from '@clerk/clerk-react' import React from 'react'

const JoinedOrganizations = () => { const { isLoaded, setActive, userMemberships } = useOrganizationList({ userMemberships: { infinite: true, }, })

if (!isLoaded) {
  return <>Loading</>
}

return (
  <>
    <ul>
      {userMemberships.data?.map((mem) => (
        <li key={mem.id}>
          <span>{mem.organization.name}</span>
          <button onClick={() => setActive({ organization: mem.organization.id })}>Select</button>
        </li>
      ))}
    </ul>

    <button disabled={!userMemberships.hasNextPage} onClick={() => userMemberships.fetchNext()}>
      Load more
    </button>
  </>
)

}

export default JoinedOrganizations

</If>

<If sdk="nextjs">
```tsx {{ filename: 'components/JoinedOrganizations.tsx' }}
'use client'

import { useOrganizationList } from '@clerk/nextjs'

export const JoinedOrganizations = () => {
  const { isLoaded, setActive, userMemberships } = useOrganizationList({
    userMemberships: {
      infinite: true,
    },
  })

  if (!isLoaded) {
    return <>Loading</>
  }

  return (
    <>
      <ul>
        {userMemberships.data?.map((mem) => (
          <li key={mem.id}>
            <span>{mem.organization.name}</span>
            <button onClick={() => setActive({ organization: mem.organization.id })}>Select</button>
          </li>
        ))}
      </ul>

      <button disabled={!userMemberships.hasNextPage} onClick={() => userMemberships.fetchNext()}>
        Load more
      </button>
    </>
  )
}
</If> <If sdk="react-router"> ```tsx {{ filename: 'components/JoinedOrganizations.tsx' }} import { useOrganizationList } from '@clerk/react-router'

export function JoinedOrganizations() { const { isLoaded, setActive, userMemberships } = useOrganizationList({ userMemberships: { infinite: true, }, })

if (!isLoaded) {
  return <>Loading</>
}

return (
  <>
    <ul>
      {userMemberships.data?.map((mem) => (
        <li key={mem.id}>
          <span>{mem.organization.name}</span>
          <button onClick={() => setActive({ organization: mem.organization.id })}>Select</button>
        </li>
      ))}
    </ul>

    <button disabled={!userMemberships.hasNextPage} onClick={() => userMemberships.fetchNext()}>
      Load more
    </button>
  </>
)

}

</If>

<If sdk="chrome-extension">
```jsx {{ filename: 'components/JoinedOrganizations.tsx' }}
import { useOrganizationList } from '@clerk/chrome-extension'

export function JoinedOrganizations() {
  const { isLoaded, setActive, userMemberships } = useOrganizationList({
    userMemberships: {
      infinite: true,
    },
  })

  if (!isLoaded) {
    return <>Loading</>
  }

  return (
    <>
      <ul>
        {userMemberships.data?.map((mem) => (
          <li key={mem.id}>
            <span>{mem.organization.name}</span>
            <button onClick={() => setActive({ organization: mem.organization.id })}>Select</button>
          </li>
        ))}
      </ul>

      <button disabled={!userMemberships.hasNextPage} onClick={() => userMemberships.fetchNext()}>
        Load more
      </button>
    </>
  )
}
</If> <If sdk="remix"> ```tsx {{ filename: 'components/JoinedOrganizations.tsx' }} import { useOrganizationList } from '@clerk/remix'

export function JoinedOrganizations() { const { isLoaded, setActive, userMemberships } = useOrganizationList({ userMemberships: { infinite: true, }, })

if (!isLoaded) {
  return <>Loading</>
}

return (
  <>
    <ul>
      {userMemberships.data?.map((mem) => (
        <li key={mem.id}>
          <span>{mem.organization.name}</span>
          <button onClick={() => setActive({ organization: mem.organization.id })}>Select</button>
        </li>
      ))}
    </ul>

    <button disabled={!userMemberships.hasNextPage} onClick={() => userMemberships.fetchNext()}>
      Load more
    </button>
  </>
)

}

</If>

<If sdk="tanstack-react-start">
```tsx {{ filename: 'components/JoinedOrganizations.tsx' }}
import { useOrganizationList } from '@clerk/tanstack-react-start'

export function JoinedOrganizations() {
  const { isLoaded, setActive, userMemberships } = useOrganizationList({
    userMemberships: {
      infinite: true,
    },
  })

  if (!isLoaded) {
    return <>Loading</>
  }

  return (
    <>
      <ul>
        {userMemberships.data?.map((mem) => (
          <li key={mem.id}>
            <span>{mem.organization.name}</span>
            <button onClick={() => setActive({ organization: mem.organization.id })}>Select</button>
          </li>
        ))}
      </ul>

      <button disabled={!userMemberships.hasNextPage} onClick={() => userMemberships.fetchNext()}>
        Load more
      </button>
    </>
  )
}
</If> <If sdk="expo"> ```tsx {{ filename: 'components/JoinedOrganizations.tsx' }} import { useOrganizationList } from '@clerk/clerk-expo' import { Text, View, TouchableOpacity, ScrollView } from 'react-native'

export function JoinedOrganizations() { const { isLoaded, setActive, userMemberships } = useOrganizationList({ userMemberships: { infinite: true, }, })

if (!isLoaded) {
  return <Text>Loading</Text>
}

return (
  <View>
    <ScrollView>
      {userMemberships.data?.map((mem) => (
        <View key={mem.id}>
          <Text>{mem.organization.name}</Text>
          <TouchableOpacity onPress={() => setActive({ organization: mem.organization.id })}>
            <Text>Select</Text>
          </TouchableOpacity>
        </View>
      ))}
    </ScrollView>

    <TouchableOpacity
      disabled={!userMemberships.hasNextPage}
      onPress={() => userMemberships.fetchNext()}
    >
      <Text>Load more</Text>
    </TouchableOpacity>
  </View>
)

}

</If>

### Simple pagination

The following example demonstrates how to use the `fetchPrevious` and `fetchNext` helper functions to paginate through the data. The `userInvitations` attribute will be populated with the first page of invitations. When the "Previous page" or "Next page" button is clicked, the `fetchPrevious` or `fetchNext` helper function will be called to fetch the previous or next page of invitations.

Notice the difference between this example's pagination and the infinite pagination example above.

<If sdk="react">
```tsx {{ filename: 'src/components/UserInvitationsTable.tsx' }}
import { useOrganizationList } from '@clerk/clerk-react'
import React from 'react'

const UserInvitationsTable = () => {
  const { isLoaded, userInvitations } = useOrganizationList({
    userInvitations: {
      infinite: true,
      keepPreviousData: true,
    },
  })

  if (!isLoaded || userInvitations.isLoading) {
    return <>Loading</>
  }

  return (
    <>
      <table>
        <thead>
          <tr>
            <th>Email</th>
            <th>Org name</th>
          </tr>
        </thead>

        <tbody>
          {userInvitations.data?.map((inv) => (
            <tr key={inv.id}>
              <th>{inv.emailAddress}</th>
              <th>{inv.publicOrganizationData.name}</th>
            </tr>
          ))}
        </tbody>
      </table>

      <button disabled={!userInvitations.hasPreviousPage} onClick={userInvitations.fetchPrevious}>
        Prev
      </button>
      <button disabled={!userInvitations.hasNextPage} onClick={userInvitations.fetchNext}>
        Next
      </button>
    </>
  )
}

export default UserInvitationsTable
</If> <If sdk="nextjs"> ```tsx {{ filename: 'components/UserInvitationsTable.tsx' }} 'use client'

import { useOrganizationList } from '@clerk/nextjs'

export const UserInvitationsTable = () => { const { isLoaded, userInvitations } = useOrganizationList({ userInvitations: { infinite: true, keepPreviousData: true, }, })

if (!isLoaded || userInvitations.isLoading) {
  return <>Loading</>
}

return (
  <>
    <table>
      <thead>
        <tr>
          <th>Email</th>
          <th>Org name</th>
        </tr>
      </thead>

      <tbody>
        {userInvitations.data?.map((inv) => (
          <tr key={inv.id}>
            <th>{inv.emailAddress}</th>
            <th>{inv.publicOrganizationData.name}</th>
          </tr>
        ))}
      </tbody>
    </table>

    <button disabled={!userInvitations.hasPreviousPage} onClick={userInvitations.fetchPrevious}>
      Prev
    </button>
    <button disabled={!userInvitations.hasNextPage} onClick={userInvitations.fetchNext}>
      Next
    </button>
  </>
)

}

</If>

<If sdk="react-router">
```tsx {{ filename: 'components/UserInvitationsTable.tsx' }}
import { useOrganizationList } from '@clerk/react-router'

export function UserInvitationsTable() {
  const { isLoaded, userInvitations } = useOrganizationList({
    userInvitations: {
      infinite: true,
      keepPreviousData: true,
    },
  })

  if (!isLoaded || userInvitations.isLoading) {
    return <>Loading</>
  }

  return (
    <>
      <table>
        <thead>
          <tr>
            <th>Email</th>
            <th>Org name</th>
          </tr>
        </thead>

        <tbody>
          {userInvitations.data?.map((inv) => (
            <tr key={inv.id}>
              <th>{inv.emailAddress}</th>
              <th>{inv.publicOrganizationData.name}</th>
            </tr>
          ))}
        </tbody>
      </table>

      <button disabled={!userInvitations.hasPreviousPage} onClick={userInvitations.fetchPrevious}>
        Prev
      </button>
      <button disabled={!userInvitations.hasNextPage} onClick={userInvitations.fetchNext}>
        Next
      </button>
    </>
  )
}
</If> <If sdk="chrome-extension"> ```jsx {{ filename: 'components/UserInvitationsTable.tsx' }} import { useOrganizationList } from '@clerk/chrome-extension'

export function UserInvitationsTable() { const { isLoaded, userInvitations } = useOrganizationList({ userInvitations: { infinite: true, keepPreviousData: true, }, })

if (!isLoaded || userInvitations.isLoading) {
  return <>Loading</>
}

return (
  <>
    <table>
      <thead>
        <tr>
          <th>Email</th>
          <th>Org name</th>
        </tr>
      </thead>

      <tbody>
        {userInvitations.data?.map((inv) => (
          <tr key={inv.id}>
            <th>{inv.emailAddress}</th>
            <th>{inv.publicOrganizationData.name}</th>
          </tr>
        ))}
      </tbody>
    </table>

    <button disabled={!userInvitations.hasPreviousPage} onClick={userInvitations.fetchPrevious}>
      Prev
    </button>
    <button disabled={!userInvitations.hasNextPage} onClick={userInvitations.fetchNext}>
      Next
    </button>
  </>
)

}

</If>

<If sdk="remix">
```tsx {{ filename: 'components/UserInvitationsTable.tsx' }}
import { useOrganizationList } from '@clerk/remix'

export function UserInvitationsTable() {
  const { isLoaded, userInvitations } = useOrganizationList({
    userInvitations: {
      infinite: true,
      keepPreviousData: true,
    },
  })

  if (!isLoaded || userInvitations.isLoading) {
    return <>Loading</>
  }

  return (
    <>
      <table>
        <thead>
          <tr>
            <th>Email</th>
            <th>Org name</th>
          </tr>
        </thead>

        <tbody>
          {userInvitations.data?.map((inv) => (
            <tr key={inv.id}>
              <th>{inv.emailAddress}</th>
              <th>{inv.publicOrganizationData.name}</th>
            </tr>
          ))}
        </tbody>
      </table>

      <button disabled={!userInvitations.hasPreviousPage} onClick={userInvitations.fetchPrevious}>
        Prev
      </button>
      <button disabled={!userInvitations.hasNextPage} onClick={userInvitations.fetchNext}>
        Next
      </button>
    </>
  )
}
</If> <If sdk="tanstack-react-start"> ```tsx {{ filename: 'components/UserInvitationsTable.tsx' }} import { useOrganizationList } from '@clerk/tanstack-react-start'

export function UserInvitationsTable() { const { isLoaded, userInvitations } = useOrganizationList({ userInvitations: { infinite: true, keepPreviousData: true, }, })

if (!isLoaded || userInvitations.isLoading) {
  return <>Loading</>
}

return (
  <>
    <table>
      <thead>
        <tr>
          <th>Email</th>
          <th>Org name</th>
        </tr>
      </thead>

      <tbody>
        {userInvitations.data?.map((inv) => (
          <tr key={inv.id}>
            <th>{inv.emailAddress}</th>
            <th>{inv.publicOrganizationData.name}</th>
          </tr>
        ))}
      </tbody>
    </table>

    <button disabled={!userInvitations.hasPreviousPage} onClick={userInvitations.fetchPrevious}>
      Prev
    </button>
    <button disabled={!userInvitations.hasNextPage} onClick={userInvitations.fetchNext}>
      Next
    </button>
  </>
)

}

</If>

<If sdk="expo">
```tsx {{ filename: 'components/UserInvitationsTable.tsx' }}
import { useOrganizationList } from '@clerk/clerk-expo'
import { Text, View, TouchableOpacity, ScrollView } from 'react-native'

export function UserInvitationsTable() {
  const { isLoaded, userInvitations } = useOrganizationList({
    userInvitations: {
      keepPreviousData: true,
    },
  })

  if (!isLoaded || userInvitations.isLoading) {
    return <Text>Loading</Text>
  }

  return (
    <View>
      <ScrollView>
        <View>
          <Text>Email</Text>
          <Text>Org name</Text>
        </View>

        {userInvitations.data?.map((inv) => (
          <View key={inv.id}>
            <Text>{inv.emailAddress}</Text>
            <Text>{inv.publicOrganizationData.name}</Text>
          </View>
        ))}
      </ScrollView>

      <TouchableOpacity
        disabled={!userInvitations.hasPreviousPage}
        onPress={userInvitations.fetchPrevious}
      >
        <Text>Prev</Text>
      </TouchableOpacity>
      <TouchableOpacity disabled={!userInvitations.hasNextPage} onPress={userInvitations.fetchNext}>
        <Text>Next</Text>
      </TouchableOpacity>
    </View>
  )
}
</If>

Properties

useOrganizationList() accepts a single object with the following properties:

<Typedoc src="shared/use-organization-list-params" />

[!WARNING] By default, the userMemberships, userInvitations, and userSuggestions attributes are not populated. To fetch and paginate the data, you must pass true or an object with the desired properties.

Shared properties

Optional properties that are shared across the userMemberships, userInvitations, and userSuggestions properties.

<Typedoc src="shared/pages-or-infinite-options" /> <Typedoc src="shared/paginated-hook-config" />

Returns

<Typedoc src="shared/use-organization-list-return" />

CreateOrganizationParams

<Typedoc src="types/create-organization-params" />

PaginatedResources

<Typedoc src="shared/paginated-resources" />

To see the different organization features integrated into one application, take a look at our organizations demo repository.

ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•šā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•

← Root | ↑ Up