Limited offer: $250 off for the first 200 customers!Claim discount

Buttons

Action components for checkout, auth, billing, navigation, and lead capture.

ButtonPrimary

The base CTA button. Renders as a <Link> when href is provided, a plain <a> for hash-only anchors, and a <button> otherwise. All other button components in the boilerplate are built on top of this one.

import ButtonPrimary from "@/components/ButtonPrimary";

<ButtonPrimary href="/#pricing">See pricing</ButtonPrimary>
<ButtonPrimary href="#features">Learn more</ButtonPrimary>
<ButtonPrimary onClick={handleClick}>Get started</ButtonPrimary>
  • href — when set, renders as a link. Hash-only values like #features use a plain <a> to avoid unnecessary Next.js prefetch requests.
  • variant"solid" (default, amber background) or "gradient" (amber-to-orange gradient). Both are amber-toned to match the default theme.
  • className — appended to the base classes. Use it to control padding, width, or override colors.
  • All standard ButtonHTMLAttributes are forwarded — disabled, type, aria-*, etc.

ButtonGradient

A gradient variant of ButtonPrimary with a subtle lift-on-hover effect. Use it for hero or section CTAs where you want more visual weight than the solid style.

import ButtonGradient from "@/components/ButtonGradient";

<ButtonGradient>Get started</ButtonGradient>
<ButtonGradient title="Join now" />

Pass content as children, or use the title prop as a shorthand fallback when no children are provided. Accepts all standard button attributes.

ButtonCheckout

Starts a checkout session for a specific plan. Takes a raw price ID (Stripe) or variant ID (Lemon Squeezy) — not a plan name. The active provider is read from config.paymentProvider.

import ButtonCheckout from "@/components/ButtonCheckout";

<ButtonCheckout planId="price_xxx" mode="payment" label="Buy now" />
<ButtonCheckout planId="price_yyy" mode="subscription" label="Subscribe" />
  • planId — the Stripe price_ ID or Lemon Squeezy variant ID. Required.
  • mode"payment" for a one-time charge, "subscription" for recurring. Defaults to "payment".
  • label — button text. Defaults to "Buy now".
  • fullWidth — when true (default), the button stretches to fill its container. Set to false for inline use.
NoteThe Pricing component uses this internally — it resolves the plan name to a price ID for you. Use ButtonCheckout directly only when you need to place a checkout button outside the pricing section.

ButtonSignin

A sign-in trigger. By default it fires a Google OAuth popup inline. Pass asLink to redirect to the sign-in page instead.

import ButtonSignin from "@/components/ButtonSignin";

<ButtonSignin />
<ButtonSignin asLink text="Log in" />
  • asLink — when true, renders as a link to config.auth.loginUrl instead of triggering OAuth inline. Use this in the header or nav.
  • text — button label. Defaults to "Sign in".
  • provider — OAuth provider. Currently only "google" is supported.

ButtonAccount

An authenticated-user dropdown. Shows the user's avatar (or an initial fallback), and a menu with links to the dashboard, a billing portal redirect, and sign-out.

import ButtonAccount from "@/components/ButtonAccount";

<ButtonAccount user={user} billingProvider="stripe" />
  • user — an object with optional name, email, and avatarUrl fields. Broken or malformed avatar URLs fall back to the user's initial automatically.
  • billingProvider"stripe" or "lemonsqueezy". Determines which portal API endpoint the "Manage billing" button calls. Defaults to "stripe".

ButtonBillingPortal

Opens the Stripe or Lemon Squeezy customer portal in the same tab. After the user is done, the provider redirects them back to the current page.

import ButtonBillingPortal from "@/components/ButtonBillingPortal";

<ButtonBillingPortal provider="stripe" />
  • provider"stripe" (default) or "lemonsqueezy". Controls which portal API is called.

ButtonLead

An inline email capture form — an input and a submit button in one component. POSTs the email to /api/lead and shows a success or error state automatically. Used by the LeadMagnet component.

import ButtonLead from "@/components/ButtonLead";

<ButtonLead cta="Join the waitlist" />
  • cta — the submit button label. Defaults to "Join the waitlist".
  • endpoint — the API route to POST to. Defaults to "/api/lead".

ButtonPopover

A generic popover anchor. Renders a trigger element (any JSX) and an absolutely-positioned panel that appears on click and closes on outside click or Escape.

import ButtonPopover from "@/components/ButtonPopover";

<ButtonPopover trigger={<span>Options</span>} align="right">
  <p>Popover content here.</p>
</ButtonPopover>
  • trigger — any JSX rendered as the clickable anchor element.
  • children — the panel content rendered inside the dropdown.
  • align"left" (default) or "right". Controls which edge of the trigger the panel aligns to.