Onboarding screen showing current plan details with visual usage bars for storage, seats, and API calls. Perfect for SaaS post-signup flows that introduce plan limits and upgrade paths.
Onboarding screen introducing the current plan's usage limits as progress bars alongside an included/excluded feature checklist. The entire screen is static and prop-driven, with no internal interactive state.
Pro blocks install through the shadcn CLI with your license key and ship their full source. Docs and live previews stay open to everyone, so you can read every block's details first.
Swap YOUR_EMAIL and YOUR_KEY for the email and license key on your account. Find your license key on your account page.
Radix flavor
npx shadcn add "https://ui.beste.co/r/onboarding22?email=YOUR_EMAIL&license_key=YOUR_KEY"Base UI flavor
npx shadcn add "https://ui.beste.co/r-base/onboarding22?email=YOUR_EMAIL&license_key=YOUR_KEY"This installs the block to components/beste/block/onboarding22.tsx and the badge, button, and progress shadcn/ui primitives it depends on.
The installed file exports onboarding22Demo alongside the block: the exact props behind the preview above. Spread it to get a working plan overview step in one line.
import { Onboarding22, onboarding22Demo } from "@/components/beste/block/onboarding22";
export default function OnboardingPage() {
return <Onboarding22 {...onboarding22Demo} />;
}Then replace the demo with your own props. Written out, a trimmed setup looks like this:
import { Onboarding22 } from "@/components/beste/block/onboarding22";
export default function OnboardingPage() {
return (
<Onboarding22
badge={{ label: "Your Plan", variant: "secondary" }}
heading="Here's what you get"
description="You're on the Free plan. Here's an overview of your limits."
planName="Free Plan"
planBadge="Current"
usageLimits={[
{ label: "Storage", used: 0, total: 5, unit: "GB" },
{ label: "Team members", used: 1, total: 3, unit: "seats" },
{ label: "Projects", used: 0, total: 5, unit: "projects" },
]}
features={[
{ text: "Unlimited viewers", included: true },
{ text: "Community support", included: true },
{ text: "Custom domains", included: false },
{ text: "Priority support", included: false },
]}
primaryButton={{ label: "Continue", href: "/dashboard" }}
upgradeButton={{ label: "Upgrade Plan", href: "/billing" }}
/>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
badge | { label: string; variant?: "default" | "secondary" | "outline" } | – | Small badge above the heading |
heading | string | – | Main headline |
description | string | – | Supporting copy below the heading |
planName | string | – | Plan name shown at the top of the card |
planBadge | string | – | Pill label next to the plan name (e.g. "Current") |
usageLimits | UsageLimit[] | [] | Progress rows for each metered resource |
features | PlanFeature[] | [] | Two-column list of included/excluded plan features |
primaryButton | { label: string; href: string } | – | Primary CTA link |
upgradeButton | { label: string; href: string } | – | Secondary CTA link, always rendered with a leading crown icon |
labels | { stepOf?: string; usageTitle?: string; includedTitle?: string } | – | Section titles and the step counter template |
currentStep | number | 1 | Current step number, used only to fill the step-of label |
totalSteps | number | 4 | Total step count, used only to fill the step-of label |
className | string | – | Extra classes for the outer <section> |
type UsageLimit = { label: string; used: number; total: number; unit: string };
type PlanFeature = { text: string; included: boolean };Onboarding22 has no useState: it is entirely prop-driven, the progress bars and feature list simply render whatever usageLimits/features are passed with no toggling or client interaction.Math.round((used / total) * 100) (guarded to 0 when total is 0) and passed straight to the shadcn Progress component's value.features render in a fixed grid-cols-2 layout regardless of item count; excluded features (included: false) show a small dot in place of the checkmark and fade to text-muted-foreground/50.upgradeButton always renders with a leading Crown icon baked into the component, distinct from primaryButton, which never gets an icon prefix.used/total are formatted with toLocaleString() before display, so large numbers (e.g. API call limits) render with thousands separators.onboarding29
Onboarding screen for collecting company information including name, team size selector chips, and industry dropdown. Perfect for B2B SaaS apps that need organizational context during setup.
onboarding23
Onboarding screen for configuring account security including two-factor authentication, recovery email, and backup codes. Perfect for apps that prioritize security during onboarding.
onboarding21
Completion screen shown after finishing onboarding with a summary of what was configured and quick-start action links. Perfect for ending the setup flow with clear next steps.
onboarding4
Welcome screen featuring a video thumbnail with play overlay and duration badge. Perfect for product tours that use video content to demonstrate features.
onboarding17
Onboarding screen where users pick their primary goal to receive a tailored onboarding path. Each goal card shows a recommended feature set. Perfect for multi-purpose platforms.
onboarding24
Onboarding screen displaying essential keyboard shortcuts in a grouped grid layout with key badges. Perfect for productivity tools that want to accelerate user adoption.