Skip to content

Pricing

Pricing sections: plan cards with a billing toggle, a comparison table, a seat picker, a single plan and a usage estimator.

Installation & usage

npx @youj/cli add marketing-pricing

Also installs badge, button, counter, icon-check, reveal, shimmer-border, table, toggle-group, use-controllable-state, youj-core, youj-ui-core.

The CLI copies the block to blocks/marketing/pricing.tsx with every component it uses, so it’s yours to edit.

Every prop is optional and falls back to the demo, so it renders as you see it until you pass your own. Give it your data, rewrite or translate its strings through copy, and connect its actions:

pricing-view.tsx
'use client'

import Link from 'next/link'
import { Pricing, type PricingProps } from '@/blocks/marketing/pricing'

export function PricingView({ period, plans, comparison }: Pick<PricingProps, 'period' | 'plans' | 'comparison'>) {
  return (
    <Pricing
      period={period}
      plans={plans}
      comparison={comparison}
      copy={{ eyebrow: 'Pricing' }}
      linkComponent={Link}
      onPeriodChange={(period) => {
        // your code
      }}
      onSelectPlan={(plan, period) => {
        // your code
      }}
    />
  )
}

Reference

Props13 props, 3 types

Props

Pricing props
PropType
themeThemeInput

Default: the theme around it. The showcase passes the chosen preset here.

–
embeddedboolean

A section inside another page: the host lays it out (no page background, section padding or max width).

default false

false
defaultPeriodPricingPeriod
'monthly''yearly'

The billing period shown first, when uncontrolled.

default 'yearly'

'yearly'
periodPricingPeriod
'monthly''yearly'

The billing period shown, to control it.

–
onPeriodChange(period: PricingPeriod) => void

Called when the visitor switches the billing period.

–
plansPricingPlan[]

The plan cards, in order.

default the demo's Hobby, Pro and Scale

the demo's Hobby, Pro and Scale
comparisonPricingComparisonGroup[]

The comparison table's groups, one value per plan in each row. An empty array hides the table.

default the demo's three groups

the demo's three groups
onSelectPlan(plan: PricingPlan, period: PricingPeriod) => void

Called when a plan's call to action is chosen, with the period shown.

–
copyPartial<PricingCopy>

Any of the block's strings, to rewrite or translate.

–
currencystring

The currency prices are in (ISO 4217).

default 'USD'

'USD'
localestring

The locale prices are formatted for (BCP 47). Default: the app's (YoujProvider's locale), else en-US.

–
headingLevel1 | 2 | 3

The section heading's level; plan names and the comparison title sit one below.

default 2

2
linkComponentLinkComponent

The element every internal link renders as, e.g. Next.js Link.

default 'a'

'a'

PricingPlan

PricingPlan props
PropType
idRequiredstring–
nameRequiredstring–
blurbRequiredstring

One line under the name.

–
priceRequiredRecord<PricingPeriod, number>

The price per seat and month, when billed monthly or yearly.

–
ctaPricingCta

The plan's call to action; leave it out for none.

–
featuredboolean

Lifted, with a traveling border light and the "Most popular" badge.

–
featuresRequiredstring[]–

PricingCta

PricingCta props
PropType
labelRequiredstring–
hrefRequiredstring–
onClickMouseEventHandler<HTMLAnchorElement>–

PricingComparisonGroup

PricingComparisonGroup props
PropType
groupRequiredstring–
rowsRequired{ feature: string; values: PricingCell[]; }[]–
Strings17 keys for copy

Strings

copy takes any of these keys; the rest keep their defaults. A key whose text holds a value (a count, a name) takes a function.

eyebrowtitledescriptionperiodLabelmonthlyyearlysaveBadgemostPopularperUnitfreebilledMonthlybilledYearlymonthlyPricecompareTitlefeatureColumnincludednotIncluded
Built from7 components
Accessibilitylandmarks, headings, controls, tables

Accessibility

Each section is a <section> named by its own heading (aria-labelledby); the heading is an h2 by default and headingLevel changes it.

Plans labels its billing period toggle and its “included” check marks, reads a struck-through monthly price as “billed monthly”, and each plan button is described by the plan it picks (aria-describedby). Seat picker is a radio group of plans, each named and described by its title and blurb, with a labelled period and plan selector. Compare is a real table with visually hidden text for the plan and feature columns, and its folding groups use aria-expanded and aria-controls. Usage estimator’s sliders are labelled and the new total is announced in a status region. Single plan’s currency choice is a labelled control.

The buttons and links are real a and button elements with the kit’s focus ring.