Pricing Page
betaA whole pricing page, built from our website components: a floating navbar, a two-tone page title, the plans side by side, a comparison, a testimonial wall, a FAQ, and a footer.
Preview
One price for the whole team. Members are always free.
Pay for the leads and admins who run things. Everyone they invite comes along at no cost.
Plans
One team
$0forever
- Who's coming, with answer-by dates
- A calendar feed for every phone
Every team
$24a month
- Everything in Starter
- Reminder emails
- Saved agendas
- Goals
Many teams
- Everything in Team
- Shared calendars
- One bill
What each plan includes, side by side.
| Feature | Starter | Team | Business |
|---|---|---|---|
| Who's coming, with an answer-by date | Included | Included | Included |
| A calendar on everyone's phone | Included | Included | Included |
| Reminder email to whoever hasn't answered | Not included | Included | Included |
| Saved agendas and goals | Manual work | Included | Included |
| Calendars shared across teams | Not included | Not included | Included |
Teams that switched, in their own words.
We moved to Team after one quarter. The reminder emails alone save me an evening a week of chasing answers, and I know who is coming before I book the room.
Priya RamanDesign lead at a studio Members are free, so we pay for five.
Tomás OkaforOffice manager at a clinic Starter was enough for our first project. We upgraded when we needed saved agendas.
Elin SatoTeam lead at a library Less than we spent on the old chat add-on, and everyone answers now.
Marcus BellHead of operations at a bakery Business let us share calendars with the two teams we work with most. One bill, one place to look, and a named person who answers the same day.
Hana NovakOperations lead at an agency The trial was long enough to be sure.
Ana LindqvistSupport lead at a lab
Questions about paying.
Install
1. Add the registry to
components.json, once per app. Without it, the shadcn CLI looks up@txbrendanin a public list that txbrendan/ui does not control.npx shadcn@latest registry add "@txbrendan=https://txbrendan.dev/r/{name}.json"2. Add the theme, once per app. It replaces your color tokens with ones checked for contrast.
npx shadcn@latest add @txbrendan/theme3. Add the template. It also adds every component it uses. Its own files go in your
componentsfolder, and they are yours to edit.npx shadcn@latest add @txbrendan/pricing-page
Use it for
- The pricing page of a product site. Render it as the whole page, from your app's page file.
- Write every word in the props: one object for the navbar, the header, the plans, the comparison, the testimonials, the FAQ, and the footer.
- Put the plans first, under a header that says who they are for. People come to this page to see prices.
- Use `note` for what every plan shares, like the currency, tax, or a free trial.
- Use the comparison for what each plan includes, and the FAQ for billing questions, like canceling or refunds.
- Use testimonials for what customers say about the price and what it got them. Put the heading in the section's `headline`, not the wall's own `title`.
- Pass your router's link once in `renderLink`. The navbar and the footer both use it.
- Set `embedded` when you show the page inside another page, like a gallery, so it has no second main.
Avoid it for
- More than three plans. Pick the three most people choose from.
- A price or a promise you can't stand behind, like "cancel any time" when you can't.
- A hero with a product preview. That belongs on the Landing Page template.
Props
- navbar
The Navbar's props. It floats as a pill once the page scrolls, and folds into a menu below 42rem.
NavbarProps
- header
The headline at the top: the claim, the gray rest, and a line under it. It renders as the page's one h1.
HeadlineProps
- plans
The plans, one PricingCard each, side by side. Two or fewer sit in a narrower row, centered.
PricingCardProps[]
- plansLabel
Names the plans for screen readers, as a hidden h2 over the cards.
string · default "Plans"
- billing
Pricing's billing switch, over the plans, between periods like monthly and yearly. Give each plan's price and period one entry per period id.
PricingBilling
- note
A small line under the plans, like "Prices in USD, before tax."
ReactNode
- comparison
A Comparison under its own headline. Its id defaults to "compare".
{ id?: string; headline?: HeadlineProps; comparison: ComparisonProps }
- testimonials
A Testimonial Wall under its own headline, between the comparison and the FAQ. Its id defaults to "testimonials".
{ id?: string; headline?: HeadlineProps; testimonials: TestimonialWallProps }
- faq
A FAQ under its own headline. Its id defaults to "faq".
{ id?: string; headline?: HeadlineProps; faq: FaqProps }
- footer
The Footer's props: the brand, a line about you, link columns, and the legal line.
FooterProps
- renderLink
Draws every link in the navbar and the footer, unless a part sets its own.
(props: NavbarLinkProps) => ReactNode · default a plain <a>
- embedded
Renders the content in a div, not a main, for a preview inside another page.
boolean · default false
- className
Extra classes on the root, which holds the container query.
string
| Prop | Type | Default | What it does |
|---|---|---|---|
| navbar | NavbarProps | - | The Navbar's props. It floats as a pill once the page scrolls, and folds into a menu below 42rem. |
| header | HeadlineProps | - | The headline at the top: the claim, the gray rest, and a line under it. It renders as the page's one h1. |
| plans | PricingCardProps[] | - | The plans, one PricingCard each, side by side. Two or fewer sit in a narrower row, centered. |
| plansLabel | string | "Plans" | Names the plans for screen readers, as a hidden h2 over the cards. |
| billing | PricingBilling | - | Pricing's billing switch, over the plans, between periods like monthly and yearly. Give each plan's price and period one entry per period id. |
| note | ReactNode | - | A small line under the plans, like "Prices in USD, before tax." |
| comparison | { id?: string; headline?: HeadlineProps; comparison: ComparisonProps } | - | A Comparison under its own headline. Its id defaults to "compare". |
| testimonials | { id?: string; headline?: HeadlineProps; testimonials: TestimonialWallProps } | - | A Testimonial Wall under its own headline, between the comparison and the FAQ. Its id defaults to "testimonials". |
| faq | { id?: string; headline?: HeadlineProps; faq: FaqProps } | - | A FAQ under its own headline. Its id defaults to "faq". |
| footer | FooterProps | - | The Footer's props: the brand, a line about you, link columns, and the legal line. |
| renderLink | (props: NavbarLinkProps) => ReactNode | a plain <a> | Draws every link in the navbar and the footer, unless a part sets its own. |
| embedded | boolean | false | Renders the content in a div, not a main, for a preview inside another page. |
| className | string | - | Extra classes on the root, which holds the container query. |
Accessibility
- The content sits in a main landmark, between the navbar's nav and the footer, so skip links and screen readers find it.
- The header renders the page's one h1. The comparison's, the testimonials', and the FAQ's headlines are h2s.
- The plans sit in a section named by a hidden h2, so the cards' h3 titles follow in order and screen readers can jump to the plans.
- The comparison, the testimonials, and the FAQ keep clear of the floating navbar when a link jumps to their ids.
- Each part keeps its own accessibility, listed on its page.
Examples
A short pricing page
<PricingPage
navbar={{
brand: "Workspace",
links: [{ href: "/pricing", label: "Pricing", current: true }, { href: "#faq", label: "FAQ" }],
actions: <Button tone="brand" size="sm">Create a team</Button>,
}}
header={{ title: "One price per team.", muted: "Everyone on it is free." }}
plans={[
{
title: "Team",
price: "$12",
period: "a month",
features: ["Who's coming", "Reminder emails"],
action: <Button tone="brand">Start</Button>,
},
]}
note="Prices in USD, before tax."
faq={{
headline: { title: "Questions." },
faq: { items: [{ question: "Can I cancel?", answer: "Yes, from your settings." }] },
}}
footer={{
brand: "Workspace",
columns: [{ title: "Product", links: [{ href: "/pricing", label: "Pricing" }] }],
legal: "© 2026 Workspace",
}}
/>