Pricing Block
A pricing section with a monthly and yearly switch, prices that roll on change, one plan under a moving border, a feature table and a link to your FAQ.
Customize
When to use it
- The pricing page of a SaaS or subscription app
- A pricing section on a landing page, with the table turned off to keep it short
- Comparing tiers of a course, membership or game subscription
Good to know
- Plan
- Pro
- Dependencies
- motion
- Rendering
- DOM and CSS
- Reduced motion
- Respected
- Lines of code
- 374
Installation
Pricing Block is part of Pro. After purchase you're invited to the private mekai-ui/mekai-ui-pro GitHub repository: copy pricing-block.tsx into components/ui and run npm install motion.
Usage
import { PricingBlock } from "@/components/ui/pricing-block";
<PricingBlock
eyebrow="Pricing"
title="Pay for what you ship"
plans={[
{ name: "Starter", monthly: 0, yearly: 0, cta: { label: "Start free", href: "/signup" } },
{
name: "Studio",
monthly: 25,
yearly: 20,
highlighted: true,
badge: "Most popular",
cta: { label: "Choose Studio", href: "/buy/studio-monthly", yearlyHref: "/buy/studio-yearly" },
},
]}
comparison={[
{
title: "Workspace",
rows: [
{ feature: "Projects", values: ["1", "Unlimited"] },
{ feature: "Version history", values: [false, true] },
],
},
]}
faq={{ label: "Read the billing FAQ", href: "/faq#billing" }}
/>Props
16 properties| Property | Type | Default | Description |
|---|---|---|---|
| plans | PricingBlockPlan[] | — | Plans in display order. Each has a name, monthly and yearly prices per month, and optional description, features, highlighted, badge and cta. |
| title | string | — | Section heading. |
| eyebrow | string | — | Short line above the heading. |
| subtitle | string | — | Supporting line under the heading. |
| comparison | PricingComparisonGroup[] | — | Groups of feature rows. Each row has one value per plan: true, false or a short string. On narrow screens the table shows one plan at a time. |
| faq | { text?: string; label: string; href: string } | — | Closing row that links to your questions page. |
| note | string | — | Small print under the plans, such as tax or currency. |
| currency | string | "$" | Symbol placed before every price. |
| defaultCycle | "monthly" | "yearly" | "monthly" | Billing cycle on first render. |
| cycle | "monthly" | "yearly" | — | Billing cycle, for controlled use. |
| onCycleChange | (cycle) => void | — | Called when the switch changes. |
| onSelectPlan | (plan, cycle) => void | — | Called by plan buttons without an href. A cta with an href renders a link; yearlyHref replaces it on the yearly cycle. |
| color | string | "#ff784f" | Accent for the border, the highlighted button and the checks, as a hex value. |
| borderSpeed | number | 4 | Seconds for one lap of the moving border. |
| as | "h1" | "h2" | "h2" | Heading level. Use "h1" when this is the whole pricing page. |
| className | string | — | Extra classes for the section. |
Dependencies: motion