> ## Documentation Index
> Fetch the complete documentation index at: https://docs.nozle.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# PlanCard

> One plan from your catalog as a card with its price, what it includes and a select button.

`PlanCard` renders a single plan with its price, the lines read from the plan and a button, for when you lay out your pricing page yourself instead of using [`PricingTable`](/sdks/react/components/pricing-table).

**When to use**

* A custom pricing grid, carousel or comparison page.
* A "recommended plan" box next to other content.
* An upgrade prompt that shows the plan the customer would move to.

**Light**

![PlanCard for the Pro plan with its price, three lines and a Get Started button, light theme](https://mintcdn.com/nozle-d78f01d8/8jEvxrWAvqijYzbo/images/react/components/plan-card/light.png?fit=max\&auto=format\&n=8jEvxrWAvqijYzbo\&q=85\&s=8a4be8d5e35babde72481c0900616d60)

**Dark**

![PlanCard for the Pro plan with its price, three lines and a Get Started button, dark theme](https://mintcdn.com/nozle-d78f01d8/8jEvxrWAvqijYzbo/images/react/components/plan-card/dark.png?fit=max\&auto=format\&n=8jEvxrWAvqijYzbo\&q=85\&s=3d8877a15af40ff44ab01ffb9bcddec5)

**Minimal**

![PlanCard for the Pro plan with its price, three lines and a Get Started button, minimal theme](https://mintcdn.com/nozle-d78f01d8/8jEvxrWAvqijYzbo/images/react/components/plan-card/minimal.png?fit=max\&auto=format\&n=8jEvxrWAvqijYzbo\&q=85\&s=40955dd6fe332f241f28644bc8fea582)

**Neobrutal**

![PlanCard for the Pro plan with its price, three lines and a Get Started button, neobrutal theme](https://mintcdn.com/nozle-d78f01d8/8jEvxrWAvqijYzbo/images/react/components/plan-card/neobrutal.png?fit=max\&auto=format\&n=8jEvxrWAvqijYzbo\&q=85\&s=cbe9dc05069081f1c7b81c4ad9a5f58b)

**Nozle**

![PlanCard for the Pro plan with its price, three lines and a Get Started button, nozle theme](https://mintcdn.com/nozle-d78f01d8/8jEvxrWAvqijYzbo/images/react/components/plan-card/nozle.png?fit=max\&auto=format\&n=8jEvxrWAvqijYzbo\&q=85\&s=b85e8683f9461482fa47009a0696df12)

**Nozle Dark**

![PlanCard for the Pro plan with its price, three lines and a Get Started button, nozleDark theme](https://mintcdn.com/nozle-d78f01d8/8jEvxrWAvqijYzbo/images/react/components/plan-card/nozle-dark.png?fit=max\&auto=format\&n=8jEvxrWAvqijYzbo\&q=85\&s=e3986e4dc6a269b87da98fbe49ab2615)

## Importing PlanCard

```tsx theme={null}
import {
  PlanCard,
  type CreateCheckoutInput,
  type PricingPlan,
} from '@nozle-js/react'
```

## Rendering PlanCard

Pass a plan and an `onSelect` handler; the card calls it with the plan code and return URL when the "Get Started" button is clicked:

```tsx components/pro-card.tsx theme={null}
export function ProCard({ plan, currentPlanCode }: { plan: PricingPlan; currentPlanCode: string }) {
  const select = ({ planCode, returnUrl }: CreateCheckoutInput) => {
    window.location.assign(`/checkout?plan=${planCode}&return=${encodeURIComponent(returnUrl)}`)
  }
  return (
    <PlanCard
      plan={plan}
      isCurrent={currentPlanCode === plan.code}
      returnUrl="https://app.example.com/settings/billing"
      onSelect={select}
    />
  )
}
```

The card shows the name, description, price with its interval and the plan's lines from `planFeatures`. The price is formatted in the plan's currency, without decimals for whole amounts (`$29`, `$14.99`). The interval reads `month`, `year`, `week`, `quarter` or `6 months`; other intervals show as sent.

`PlanCard` does not fetch anything and does not show [Powered by Nozle](/sdks/react/components/powered-by-nozle).

## Data

The card needs one plan in the `PricingPlan` shape the public catalog returns:

```tsx theme={null}
const pro: PricingPlan = {
  code: 'pro',
  name: 'Pro',
  amount_cents: 2900,
  amount_currency: 'USD',
  interval: 'monthly',
  description: 'For growing teams',
  entitlements: [
    { feature_type: 'metered', code: 'api_calls', name: 'API calls', usage_limit: 50000 },
    { feature_type: 'metered', code: 'seats', name: 'Seats', usage_limit: 10 },
  ],
  credit_grant_rules: [{ credit_system_code: 'ai_credits', amount: '500', interval: 'month' }],
}

export function ProCard() {
  return <PlanCard plan={pro} isCurrent={false} />
}
```

### Live data

Read the plans with [`usePlans`](/sdks/react/hooks#useplans) inside `BillingProvider`, and start checkout with [`useCheckoutSession`](/sdks/react/hooks#usecheckoutsession), which calls the provider's `createCheckout`:

```tsx theme={null}
import { useState } from 'react'
import { Checkout, useCheckoutSession, usePlans } from '@nozle-js/react'

export function PlanCards({ currentPlanCode }: { currentPlanCode: string }) {
  const { plans } = usePlans()
  const { fetchClientSecret } = useCheckoutSession()
  const [clientSecret, setClientSecret] = useState<string | null>(null)

  if (clientSecret) {
    return <Checkout clientSecret={clientSecret} publishableKey="pk_live_stripe..." />
  }
  return plans.map((plan) => (
    <PlanCard
      key={plan.code}
      plan={plan}
      isCurrent={plan.code === currentPlanCode}
      onSelect={({ planCode, returnUrl }) => void fetchClientSecret(planCode, returnUrl).then(setClientSecret)}
    />
  ))
}
```

## Examples

### Current plan

With `isCurrent`, the card gets a primary-colour border, `aria-current="true"` and a disabled "Current Plan" button.

![PlanCard for the current Free plan with a disabled Current Plan button, light theme](https://mintcdn.com/nozle-d78f01d8/8jEvxrWAvqijYzbo/images/react/components/plan-card-current/light.png?fit=max\&auto=format\&n=8jEvxrWAvqijYzbo\&q=85\&s=30aee7f7fdb394c5f59cd28067ab0057)

```tsx theme={null}
export function FreeCard({ plan }: { plan: PricingPlan }) {
  return <PlanCard plan={plan} isCurrent onSelect={() => {}} />
}
```

### Panel layout

The themes `nozle` and `nozleDark` use the [panel card layout](/sdks/react/styling#plan-card-layout): the name in a header band, with a badge that reads "Active" on the current plan.

![PlanCard for the Pro plan in the panel layout with a header band, nozle theme](https://mintcdn.com/nozle-d78f01d8/8jEvxrWAvqijYzbo/images/react/components/plan-card/nozle.png?fit=max\&auto=format\&n=8jEvxrWAvqijYzbo\&q=85\&s=b85e8683f9461482fa47009a0696df12)

```tsx theme={null}
import { nozle } from '@nozle-js/react/themes'

export function ProCard({ plan }: { plan: PricingPlan }) {
  return <PlanCard plan={plan} isCurrent={false} onSelect={() => {}} appearance={{ theme: nozle }} />
}
```

### Custom lines

`features` replaces the lines read from the plan.

```tsx theme={null}
export function ProCard({ plan }: { plan: PricingPlan }) {
  return <PlanCard plan={plan} isCurrent={false} features={['Unlimited projects', 'Priority support']} />
}
```

## API reference

**plan** `PricingPlan` *required*

The plan to show: `code`, `name`, `amount_cents`, `amount_currency`, `interval`, and optional `description`, `entitlements`, `credit_grant_rules`, `charges`.

**isCurrent** `boolean` *required*

Shows the card as the customer's plan: a primary-colour border, `aria-current="true"`, and a disabled "Current Plan" button.

**features** `string[]`

Replaces the lines read from the plan. Defaults to the lines from `planFeatures(plan)`.

**onSelect** `(input: CreateCheckoutInput) =\> void`

Fires when the "Get Started" button is clicked and receives `{ planCode, returnUrl }`. Without it the card has no button.

**returnUrl** `string`

The `returnUrl` passed to `onSelect`. Defaults to the current URL.

**appearance** `Appearance`

Theme, variables and element overrides. Defaults to the provider's. See [Appearance](/sdks/react/styling).

### States

| State | What shows |
| - | - |
| Not current | The "Get Started" button, when `onSelect` is set. |
| Current plan | A primary-colour border and a disabled "Current Plan" button; in the panel layout, the "Active" badge. |
| No `onSelect` | The card without a button. |

The root has `data-testid="plan-card-<code>"`.

### Appearance

> **Element keys**
>
> `planCard` (root), `planCard__name`, `planCard__description`, `planCard__price`, `planCard__features`, `planCard__feature`, `planCard__cta`. In the [panel layout](/sdks/react/styling#plan-card-layout) also `planCard__header` and `planCard__badge`, which reads "Active" on the current plan.
>
> Style them with `appearance.elements`. See [Elements](/sdks/react/styling#elements).

## Related

> **[PricingTable](/sdks/react/components/pricing-table)**
>
> All plans with checkout built in.

> **[PlanComparison](/sdks/react/components/plan-comparison)**
>
> The plans side by side, feature by feature.

> **[CheckoutButton](/sdks/react/components/checkout-button)**
>
> A button that starts checkout for one plan.

> **[PlanBadge](/sdks/react/components/plan-badge)**
>
> The plan name as a small badge.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.