Skip to main content
Docs

<CheckoutButton /> component

The <CheckoutButton /> component renders a button that opens the checkout drawer.

The <CheckoutButton /> component renders a button that opens the checkout drawer when selected, allowing users to subscribe to a plan for either their personal account or an organization. It must be wrapped inside a <SignedIn /> component to ensure the user is authenticated.

Warning

This API is experimental and subject to change while Clerk Billing is under Beta. To mitigate potential disruptions, we recommend pinning your SDK and clerk-js package versions.

  • Name
    planId
    Type
    string
    Description

    The ID of the plan to subscribe to.

  • Name
    planPeriod?
    Type
    'month' | 'annual'
    Description

    The billing period for the subscription.

  • Name
    subscriberType?
    Type
    'user' | 'org'
    Description

    Determines whether the subscription is for the current user or organization. Defaults to 'user'.

  • Name
    children?
    Type
    React.ReactNode
    Description

    A custom button element. If not provided, defaults to a button with the text "Checkout".

  • Name
    onSubscriptionComplete?
    Type
    () => void
    Description

    A callback function that is called when a subscription is successfully completed.

  • Name
    newSubscriptionRedirectUrl?
    Type
    string
    Description

    The URL to redirect to after a successful subscription.

  • Name
    checkoutProps?
    Type
    { appearance: Appearance }
    Description

    Options for the checkout drawer. Accepts the following properties:

    • appearance: an object used to style your components. For example: <CheckoutButton checkoutProps={{ appearance: { ... } }} />.

Usage

<CheckoutButton /> must be wrapped inside a <SignedIn /> component to ensure the user is authenticated.

<>
  // ❌ This will throw an error
  <CheckoutButton planId="cplan_xxx" />
  // ✅ Correct usage
  <SignedIn>
    <CheckoutButton planId="cplan_xxx" />
  </SignedIn>
</>

<CheckoutButton /> will throw an error if the subscriberType property is set to 'org' and no active organization is set.

<>
  // ❌ This will throw an error if no organization is active
  <CheckoutButton planId="cplan_xxx" subscriberType="org" />
  // ✅ Correct usage
  {auth.orgId ? <CheckoutButton planId="cplan_xxx" subscriberType="org" /> : null}
</>

<CheckoutButton /> preserves any click handlers attached to custom button elements, while maintaining the checkout drawer functionality.

<CheckoutButton planId="cplan_xxx">
  <button onClick={() => console.log('Starting checkout')} className="custom-button">
    Start Subscription
  </button>
</CheckoutButton>
app/pricing/page.tsx
'use client'

import { SignedIn } from '@clerk/nextjs'
import { CheckoutButton } from '@clerk/nextjs/experimental'

export default function PricingPage() {
  return (
    <SignedIn>
      {/* Basic usage */}
      <CheckoutButton planId="cplan_xxx" planPeriod="month" />

      {/* Customizes the appearance of the checkout drawer */}
      <CheckoutButton
        planId="plan_123"
        planPeriod="annual"
        checkoutProps={{
          appearance: {
            /* custom theme */
          },
        }}
      />

      {/* Custom button */}
      <CheckoutButton
        planId="cplan_xxx"
        planPeriod="annual"
        onSubscriptionComplete={() => {
          console.log('Subscription completed!')
        }}
        newSubscriptionRedirectUrl="/dashboard"
      >
        <button className="custom-button">
          <Icon name="credit-card" />
          Subscribe Now - $9.99/month
        </button>
      </CheckoutButton>
    </SignedIn>
  )
}
src/components/PricingSection.tsx
import { SignedIn } from '@clerk/clerk-react'
import { CheckoutButton } from '@clerk/clerk-react/experimental'

const PricingSection = () => {
  return (
    <SignedIn>
      {/* Basic usage */}
      <CheckoutButton planId="cplan_xxx" planPeriod="month" />

      {/* Customizes the appearance of the checkout drawer */}
      <CheckoutButton
        planId="cplan_xxx"
        planPeriod="annual"
        checkoutProps={{
          appearance: {
            /* custom theme */
          },
        }}
      />

      {/* Custom button */}
      <CheckoutButton
        planId="cplan_xxx"
        planPeriod="annual"
        onSubscriptionComplete={() => {
          console.log('Subscription completed!')
        }}
        newSubscriptionRedirectUrl="/dashboard"
      >
        <button className="custom-button">
          <Icon name="credit-card" />
          Subscribe Now - $9.99/month
        </button>
      </CheckoutButton>
    </SignedIn>
  )
}

export default PricingSection

Feedback

What did you think of this content?

Last updated on