Skip to main content
Docs

usePlans()

Warning

Billing is currently in Beta and its APIs are experimental and may undergo breaking changes. To mitigate potential disruptions, we recommend pinning your SDK and clerk-js package versions.

The usePlans() hook provides access to the subscription plans available in your application. It returns a paginated list of plans and includes methods for managing them.

Parameters

usePlans() accepts a single optional object with the following properties:

  • Name
    enabled?
    Type
    boolean
    Description

    If true, a request will be triggered when the hook is mounted. Defaults to true.

  • Name
    for?
    Type
    "user" | "organization"
    Description

    Specifies whether to fetch for the current user or organization. Defaults to 'user'.

  • Name
    infinite?
    Type
    boolean
    Description

    If true, newly fetched data will be appended to the existing list rather than replacing it. Useful for implementing infinite scroll functionality. Defaults to false.

  • Name
    initialPage?
    Type
    number
    Description

    A number that specifies which page to fetch. For example, if initialPage is set to 10, it will skip the first 9 pages and fetch the 10th page. Defaults to 1.

  • Name
    keepPreviousData?
    Type
    boolean
    Description

    If true, the previous data will be kept in the cache until new data is fetched. Defaults to false.

  • Name
    pageSize?
    Type
    number
    Description

    A number that specifies the maximum number of results to return per page. Defaults to 10.

Returns

usePlans() returns an object with the following properties:

  • Name
    count
    Type
    number
    Description

    The total count of data that exist remotely.

  • Name
    data
    Type
    BillingPlanResourceJavaScript Icon[]
    Description

    An array that contains the fetched data. For example, for the memberships attribute, data will be an array of OrganizationMembershipJavaScript Icon objects.

  • Name
    error
    Type
    null | ClerkAPIResponseError
    Description

    Clerk's API response error object.

  • Name
    fetchNext
    Type
    () => void
    Description

    A function that triggers the next page to be loaded. This is the same as fetchPage(page => Math.min(pageCount, page + 1)).

  • Name
    fetchPage
    Type
    ValueOrSetter<number>
    Description

    A function that triggers a specific page to be loaded.

  • Name
    fetchPrevious
    Type
    () => void
    Description

    A function that triggers the previous page to be loaded. This is the same as fetchPage(page => Math.max(0, page - 1)).

  • Name
    hasNextPage
    Type
    boolean
    Description

    A boolean that indicates if there are available pages to be fetched.

  • Name
    hasPreviousPage
    Type
    boolean
    Description

    A boolean that indicates if there are available pages to be fetched.

  • Name
    isError
    Type
    boolean
    Description

    A boolean that indicates the request failed.

  • Name
    isFetching
    Type
    boolean
    Description

    A boolean that is true if there is an ongoing request or a revalidation.

  • Name
    isLoading
    Type
    boolean
    Description

    A boolean that is true if there is an ongoing request and there is no fetched data.

  • Name
    page
    Type
    number
    Description

    The current page.

  • Name
    pageCount
    Type
    number
    Description

    The total amount of pages. It is calculated based on count, initialPage, and pageSize.

  • Name
    revalidate
    Type
    () => Promise<void>
    Description

    A function that triggers a revalidation of the current page.

  • Name
    setData
    Type
    CacheSetter<undefined | ClerkPaginatedResponseJavaScript Icon<BillingPlanResourceJavaScript Icon>>
    Description

    A function that allows you to set the data manually.

Examples

Basic usage

The following example shows how to fetch and display available plans.

src/pages/billing/PlansList.tsx
import { usePlans } from '@clerk/clerk-react/experimental'

export default function PlansList() {
  const { data, isLoading, hasNextPage, fetchNext, hasPreviousPage, fetchPrevious } = usePlans({
    for: 'user',
    pageSize: 10,
  })

  if (isLoading) {
    return <div>Loading plans...</div>
  }

  return (
    <ul>
      {data?.map((plan) => (
        <li key={plan.id}>
          <h3>{plan.name}</h3>
          <p>{plan.description}</p>
          <p>Is free plan: {!plan.hasBaseFee ? 'Yes' : 'No'}</p>
          <p>
            Price per month: {plan.currency} {plan.amountFormatted}
          </p>
          <p>
            Price per year: {plan.currency} {plan.annualAmountFormatted} equivalent to{' '}
            {plan.currency} {plan.annualMonthlyAmountFormatted} per month
          </p>
          <h4>Features:</h4>
          <ul>
            {plan.features.map((feature) => (
              <li key={feature.id}>{feature.name}</li>
            ))}
          </ul>
        </li>
      ))}

      {hasNextPage && <button onClick={() => fetchNext()}>Next</button>}
      {hasPreviousPage && <button onClick={() => fetchPrevious()}>Previous</button>}
    </ul>
  )
}

Infinite pagination

The following example demonstrates how to implement infinite scrolling with plans.

src/pages/billing/PlansList.tsx
import { usePlans } from '@clerk/clerk-react/experimental'

export default function InfinitePlansList() {
  const { data, isLoading, hasNextPage, fetchNext } = usePlans({
    for: 'user',
    infinite: true,
    pageSize: 2,
  })

  if (isLoading) {
    return <div>Loading plans...</div>
  }

  return (
    <div>
      <ul>
        {data?.map((plan) => (
          <li key={plan.id}>
            <h3>{plan.name}</h3>
            <p>{plan.description}</p>
            <p>Is free plan: {!plan.hasBaseFee ? 'Yes' : 'No'}</p>
            <p>
              Price per month: {plan.currency} {plan.amountFormatted}
            </p>
            <p>
              Price per year: {plan.currency} {plan.annualAmountFormatted} equivalent to{' '}
              {plan.currency} {plan.annualMonthlyAmountFormatted} per month
            </p>
            <h4>Features:</h4>
            <ul>
              {plan.features.map((feature) => (
                <li key={feature.id}>{feature.name}</li>
              ))}
            </ul>
          </li>
        ))}
      </ul>

      {hasNextPage && <button onClick={() => fetchNext()}>Load more plans</button>}
    </div>
  )
}

Checkout flow with a new payment method

Prompt users to add a new payment method during checkout

Checkout flow for returning users

Prompt users to select an existing payment method during checkout

Feedback

What did you think of this content?

Last updated on