+ >
+ );
+}
+```
+
+
+
+
+
+```tsx {{ filename: 'app/page.tsx' }}
+'use client';
+
+import { useUser } from '@clerk/nextjs';
+
+export default function HomePage() {
+ const { isLoaded, user } = useUser();
+
+ if (!isLoaded) {
+ // Handle loading state
+ return null;
+ }
+
+ if (!user) return null;
+
+ const updateUser = async () => {
+ // Update data via an API endpoint
+ const updateMetadata = await fetch('/api/updateMetadata');
+
+ // Check if the update was successful
+ if (updateMetadata.message !== 'success') {
+ throw new Error('Error updating');
+ }
+
+ // If the update was successful, reload the user data
+ await user.reload();
+ };
+
+ return (
+ <>
+
+
user role: {user?.publicMetadata.role}
+ >
+ );
+}
+```
+
+
diff --git a/packages/shared/src/react/hooks/useClerk.ts b/packages/shared/src/react/hooks/useClerk.ts
index 931a722aaad..4f993b0eaf2 100644
--- a/packages/shared/src/react/hooks/useClerk.ts
+++ b/packages/shared/src/react/hooks/useClerk.ts
@@ -14,6 +14,9 @@ import { useAssertWrappedByClerkProvider, useClerkInstanceContext } from '../con
*
* The following example uses the `useClerk()` hook to access the `clerk` object. The `clerk` object is used to call the [`openSignIn()`](https://clerk.com/docs/references/javascript/clerk#sign-in) method to open the sign-in modal.
*
+ *
+ *
+ *
* ```tsx {{ filename: 'src/Home.tsx' }}
* import { useClerk } from '@clerk/clerk-react'
*
@@ -23,6 +26,14 @@ import { useAssertWrappedByClerkProvider, useClerkInstanceContext } from '../con
* return
* }
* ```
+ *
+ *
+ *
+ *
+ * {@include ../../../docs/use-clerk.md#nextjs-01}
+ *
+ *
+ *
*/
export const useClerk = (): LoadedClerk => {
useAssertWrappedByClerkProvider('useClerk');
diff --git a/packages/shared/src/react/hooks/useOrganization.tsx b/packages/shared/src/react/hooks/useOrganization.tsx
index 25868ab05d7..e8ff9b7ee74 100644
--- a/packages/shared/src/react/hooks/useOrganization.tsx
+++ b/packages/shared/src/react/hooks/useOrganization.tsx
@@ -22,19 +22,24 @@ import {
import type { PaginatedHookConfig, PaginatedResources, PaginatedResourcesWithDefault } from '../types';
import { usePagesOrInfinite, useWithSafeValues } from './usePagesOrInfinite';
-type UseOrganizationParams = {
+/**
+ * @interface
+ */
+export type UseOrganizationParams = {
/**
* If set to `true`, all default properties will be used.
*
* Otherwise, accepts an object with the following optional properties:
*
* - `enrollmentMode`: A string that filters the domains by the provided enrollment mode.
+ * - Any of the properties described in [Shared properties](#shared-properties).
*/
domains?: true | PaginatedHookConfig;
/**
* If set to `true`, all default properties will be used. Otherwise, accepts an object with the following optional properties:
*
* - `status`: A string that filters the membership requests by the provided status.
+ * - Any of the properties described in [Shared properties](#shared-properties).
*/
membershipRequests?: true | PaginatedHookConfig;
/**
@@ -44,6 +49,7 @@ type UseOrganizationParams = {
*
* - `role`: An array of [`OrganizationCustomRoleKey`](/docs/references/javascript/types/organization-custom-role-key).
* - `query`: A string that filters the memberships by the provided string.
+ * - Any of the properties described in [Shared properties](#shared-properties).
*/
memberships?: true | PaginatedHookConfig;
/**
@@ -52,14 +58,15 @@ type UseOrganizationParams = {
* Otherwise, accepts an object with the following optional properties:
*
* - `status`: A string that filters the invitations by the provided status.
+ * - Any of the properties described in [Shared properties](#shared-properties).
*/
invitations?: true | PaginatedHookConfig;
};
/**
- * @inline
+ * @interface
*/
-type UseOrganizationReturn =
+export type UseOrganizationReturn =
| {
/**
* A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads.
@@ -121,8 +128,6 @@ type UseOrganizationReturn =
> | null;
};
-type UseOrganization = (params?: T) => UseOrganizationReturn;
-
const undefinedPaginatedResource = {
data: undefined,
count: undefined,
@@ -149,7 +154,7 @@ const undefinedPaginatedResource = {
*
* To keep network usage to a minimum, developers are required to opt-in by specifying which resource they need to fetch and paginate through. By default, the `memberships`, `invitations`, `membershipRequests`, and `domains` attributes are not populated. You must pass `true` or an object with the desired properties to fetch and paginate the data.
*
- * ```jsx
+ * ```tsx
* // invitations.data will never be populated.
* const { invitations } = useOrganization()
*
@@ -179,7 +184,7 @@ const undefinedPaginatedResource = {
*
* The following example demonstrates how to use the `infinite` property to fetch and append new data to the existing list. The `memberships` attribute will be populated with the first page of the organization's 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.
*
- * ```jsx
+ * ```tsx
* import { useOrganization } from '@clerk/clerk-react'
*
* export default function MemberList() {
@@ -225,7 +230,7 @@ const undefinedPaginatedResource = {
*
* Notice the difference between this example's pagination and the infinite pagination example above.
*
- * ```jsx
+ * ```tsx
* import { useOrganization } from '@clerk/clerk-react'
*
* export default function MemberList() {
@@ -264,7 +269,7 @@ const undefinedPaginatedResource = {
* }
* ```
*/
-export const useOrganization: UseOrganization = params => {
+export function useOrganization(params?: T): UseOrganizationReturn {
const {
domains: domainListParams,
membershipRequests: membershipRequestsListParams,
@@ -462,4 +467,4 @@ export const useOrganization: UseOrganization = params => {
memberships,
invitations,
};
-};
+}
diff --git a/packages/shared/src/react/hooks/useOrganizationList.tsx b/packages/shared/src/react/hooks/useOrganizationList.tsx
index 59febf948e8..47d062d411d 100644
--- a/packages/shared/src/react/hooks/useOrganizationList.tsx
+++ b/packages/shared/src/react/hooks/useOrganizationList.tsx
@@ -16,17 +16,34 @@ import { useAssertWrappedByClerkProvider, useClerkInstanceContext, useUserContex
import type { PaginatedHookConfig, PaginatedResources, PaginatedResourcesWithDefault } from '../types';
import { usePagesOrInfinite, useWithSafeValues } from './usePagesOrInfinite';
-type UseOrganizationListParams = {
+/**
+ * @interface
+ */
+export type UseOrganizationListParams = {
/**
- * `true` or an object with any of the properties described in [Shared properties](https://clerk.com/docs/references/react/use-organization-list#shared-properties). If set to `true`, all default properties will be used.
+ * If set to `true`, all default properties will be used.
+ *
+ * Otherwise, accepts an object with the following optional properties:
+ *
+ * - Any of the properties described in [Shared properties](#shared-properties).
*/
userMemberships?: true | PaginatedHookConfig;
/**
- * `true` or an object with [`status: OrganizationInvitationStatus`](https://clerk.com/docs/references/react/use-organization-list#organization-invitation-status) or any of the properties described in [Shared properties](https://clerk.com/docs/references/react/use-organization-list#shared-properties). If set to `true`, all default properties will be used.
+ * If set to `true`, all default properties will be used.
+ *
+ * Otherwise, accepts an object with the following optional properties:
+ *
+ * - `status`: A string that filters the invitations by the provided status.
+ * - Any of the properties described in [Shared properties](#shared-properties).
*/
userInvitations?: true | PaginatedHookConfig;
/**
- * `true` or an object with [`status: OrganizationSuggestionsStatus | OrganizationSuggestionStatus[]`](https://clerk.com/docs/references/react/use-organization-list#organization-suggestion-status) or any of the properties described in [Shared properties](https://clerk.com/docs/references/react/use-organization-list#shared-properties). If set to `true`, all default properties will be used.
+ * If set to `true`, all default properties will be used.
+ *
+ * Otherwise, accepts an object with the following optional properties:
+ *
+ * - `status`: A string that filters the suggestions by the provided status.
+ * - Any of the properties described in [Shared properties](#shared-properties).
*/
userSuggestions?: true | PaginatedHookConfig;
};
@@ -49,9 +66,10 @@ const undefinedPaginatedResource = {
setData: undefined,
} as const;
-type UseOrganizationList = (
- params?: T,
-) =>
+/**
+ * @interface
+ */
+export type UseOrganizationListReturn =
| {
/**
* A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads.
@@ -79,35 +97,17 @@ type UseOrganizationList = (
userSuggestions: PaginatedResourcesWithDefault;
}
| {
- /**
- * A boolean that indicates whether Clerk has completed initialization. Initially `false`, becomes `true` once Clerk loads.
- */
isLoaded: boolean;
- /**
- * A function that returns a `Promise` which resolves to the newly created `Organization`.
- */
createOrganization: (params: CreateOrganizationParams) => Promise;
- /**
- * A function that sets the active session and/or organization.
- */
setActive: SetActive;
- /**
- * Returns `PaginatedResources` which includes a list of the user's organization memberships.
- */
userMemberships: PaginatedResources<
OrganizationMembershipResource,
T['userMemberships'] extends { infinite: true } ? true : false
>;
- /**
- * Returns `PaginatedResources` which includes a list of the user's organization invitations.
- */
userInvitations: PaginatedResources<
UserOrganizationInvitationResource,
T['userInvitations'] extends { infinite: true } ? true : false
>;
- /**
- * Returns `PaginatedResources` which includes a list of suggestions for organizations that the user can join.
- */
userSuggestions: PaginatedResources<
OrganizationSuggestionResource,
T['userSuggestions'] extends { infinite: true } ? true : false
@@ -116,8 +116,135 @@ type UseOrganizationList = (
/**
* 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.
+ *
+ * @example
+ * ### 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.
+ *
+ * ```tsx
+ * // 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,
+ * },
+ * })
+ * ```
+ *
+ * @example
+ * ### 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.
+ *
+ * ```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 (
+ * <>
+ *
+ * {userMemberships.data?.map((mem) => (
+ *
+ * {mem.organization.name}
+ *
+ *
+ * ))}
+ *
+ *
+ *
+ * >
+ * )
+ * }
+ *
+ * export default JoinedOrganizations
+ * ```
+ *
+ * @example
+ * ### 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.
+ *
+ * ```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 (
+ * <>
+ *