Billing Gift Subscription
A gifting form for letting one user pay for another user's subscription. Duration is picked from a row of selectable cards with one-time prices, there's a recipient email field and a personal message textarea with a live character count, and the price preview at the bottom always matches the selected duration. Built for consumer products, educational platforms, and pro-tool upgrades where gifting is a growth lever.
Docs
Installation
A real shadcn registry command, not a copy-paste stand-in: it fetches this block plus its button, input, label, textarea dependencies and any missing npm packages, and installs them straight into your project.
npx shadcn add https://staaarter.com/r/billing-gift-subscription.jsonPrefer not to use the CLI? Copy the source from the Code toggle above into src/components/blocks/billing/billing62.tsx instead.
Usage
The file also exports billing62Demo, the exact props behind the preview above. Spread it to get a working section in one line, then replace it with your own data.
import { Billing62, billing62Demo } from "@/components/blocks/billing/billing62"; export default function Page() { return <Billing62 {...billing62Demo} />; }
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| heading | string | "Gift a subscription" | Card heading. |
| description | string | none | Optional supporting text under the heading. |
| durations | GiftDuration[] | none | Duration options rendered as selectable cards, in the order given. |
| defaultDurationId | string | durations[0].id | Which duration is selected on first render. |
| recipientLabel | string | "Recipient email" | Label for the recipient email field. |
| recipientPlaceholder | string | "friend@example.com" | Placeholder for the recipient email field. |
| messageLabel | string | "Personal message" | Label for the message textarea. |
| messagePlaceholder | string | none | Placeholder for the message textarea. |
| maxMessageLength | number | 200 | Character limit enforced on the message field and shown in the counter. |
| ctaLabel | string | "Send gift" | Label on the submit button. |
| className | string | none | Extra classes for the outer container. |
Types
interface GiftDuration { id: string; label: string; price: number; }
Behavior notes
- Selected duration and the message text are both local state; the price preview at the bottom always reflects the currently selected duration.
- The message textarea is capped at maxMessageLength via the native maxLength attribute, and the counter above it updates as the user types.
- The recipient email field is a plain uncontrolled input; read its value from the surrounding form on submit rather than from component state, since it isn't tracked internally.
- Duration cards are real buttons in a radiogroup, so switching duration works with keyboard navigation and screen readers, not only pointer clicks.
- The submit button doesn't call anything on its own. Wrap the fields in a form and handle submission yourself, or lift state up if you need the selected duration and message outside the component.
Frequently asked questions
More Billing Blocks
View all →Billing Invoice List
Invoice history table with status badges, formatted amounts, and a per-row download link, built with shadcn/ui and Tailwind CSS.
Billing Failed Payment Alert
High-contrast failed-payment alert with a message, a retry button, and an optional update-payment-method button, built with shadcn/ui and Tailwind CSS.
Billing Credit Balance
Compact credit balance card with a large total, an optional purchased-versus-promotional breakdown, a low-balance notice, and a top-up button.
Billing Payment Methods
A saved payment method list for React and Next.js with brand icons, a default badge, near-expiry warnings, and remove/set-default actions per row.
Billing Add Card
A card entry form for React and Next.js with auto-formatted fields, internal brand detection, and per-field validation feedback built with shadcn/ui and Tailwind CSS.
Billing Coupon Code
An inline promo code input for React and Next.js with a simulated loading state, an applied summary showing the discount amount, and an invalid-code message.