WingoUI
Buttons & Actions
ButtonButton GroupCopy ButtonDelete ButtonTheme ToggleToggleToggle Group
Inputs
Avatar UploadCalendarCheckboxColor PickerComboboxCron PickerCurrency InputDate PickerDate Range PickerDate Time PickerDuration PickerEmail InputFile UploadFilter BuilderInputInput GroupListboxMasked InputMention InputMonth PickerMulti SelectNumber InputOTP InputPassword InputPhone InputRadio GroupRatingSearch InputSegmented ControlSelectSignature PadSliderSwitchTag InputTextareaTime Picker
Forms
Address InputCSV ImportFieldForm WizardInline EditInvoice line itemsRich Text EditorSchema Builder
Navigation
Back To TopBounce SidebarBreadcrumbCommand MenuGlobal SearchGooey NavHook SidebarNav MenuNav TabsPaginationProximity SidebarScroll ProgressSidebarStepsTable Of ContentsTabsTopbarUser MenuWorkspace Switcher
Overlays
Alert DialogContext MenuDialogDrawerDropdown MenuFamily DrawerHover CardPopoverSheetShortcuts DialogTooltipTour
Feedback
AlertBannerCookie ConsentEmoji ReactionEmpty StateNotification BellNotification CenterProgressRoute ProgressSkeletonSpinnerToast
Data Display
Approval FlowAvatarBadgeCalendar ViewCode BlockComment ThreadContact cardCountdownDescription ListDiff ViewerFile ListFile managerFolderGanttJSON ViewerKbdLog ViewerMarkdownPresenceSchedulerTagTimelineTree View
Tables & Lists
Audit LogData TableDeal PipelineEditable GridKanbanListMembers tablePermissions MatrixTableTask ListVirtual List
Charts & Stats
Animated CounterArea chartBar chartDonut chartFunnel chartGaugeGitHub ActivityHeatmap calendarLeaderboardLine chartRadial barSparklineStat CardTrackerTrend badge
Layout
AccordionApp ShellCardCollapsibleDetail LayoutEntity HeaderPage HeaderScroll AreaSeparatorSettings LayoutSplit ViewToolbar
Media
Audio PlayerCarouselCSV ViewerDOCX EditorDOCX ViewerExcel ViewerFile SystemImage CropperImage LightboxLocation MapPDF ViewerPowerPoint ViewerQR CodeStep PlayerVideo Player
AI Kit
Agent Status CardChat MessageChat ThreadConversation ListFluid OrbGrid RevealMatrix OrbModel PickerPrompt InputReasoning IndicatorRule BuilderSuggestion ChipsTool Call TimelineUsage MeterVoice InputWorkflow Canvas
Text & Effects
Gravity Letters
Mobile
Action SheetBottom Tab BarFABHaptic ButtonHero HeaderInstall PromptLarge Title HeaderNotification BannerOnboarding CarouselPicker WheelPull To RefreshSlide To ConfirmSticky CTA BarSwipe DeckSwipeable Tabs
Commerce
Cart drawerCategory pickerCheckout stepsCoupon inputFavorite buttonFilter panelListing cardListing gridOrder trackerPricePrice rangePricing tableProduct galleryQuantity stepperReviewsSeller card
Marketing Sections
App Download SectionBlog Cards SectionCTA SectionFAQ SectionFeature GridFeature ShowcaseHero SectionIntegrations SectionLogo CloudMarketing FooterMarketing HeaderMarketing SectionNewsletter SectionPricing SectionStats SectionSteps SectionTeam SectionTestimonials SectionTimeline SectionVideo Section
Blocks
Admin Dashboard PageAdmin ShellAI Chat PageAutomation Builder PageCheckout PageCRM Contact PageCRM Pipeline PageError PagesInbox PageInvoice PageKPI DashboardListing Detail PageLogin PageMarketplace Home PageMarketplace Search PageMarketplace ShellMobile App HomeOnboarding FlowPost Listing WizardPricing PageRegister PageSettings PageUsers Admin Page
Templates
About PageAcademy PageAccessibility PageAffiliate PageAI Product PageBlog PageBlog Post PageCareers PageChangelog PageCommunity PageCompare PageContact PageCustomer Story PageCustomers PageDemo Booking PageDevelopers PageDocs Home PageDownload PageEnterprise PageEvents PageExperts PageFAQ PageFeature PageGlossary PageHelp Article PageHelp Center PageIntegration Detail PageIntegrations PageJob Detail PageLanding PageLaunch PageLegal PageManifesto PagePress PageProduct Tour PageReferral PageRoadmap PageROI Calculator PageSecurity PageSolutions PageStartups PageStatus PageTemplate Gallery PageWaitlist PageYear in Review Page
Hooks & Utilities
AI ChatChart kitCommerceDate utilsFile exportFile typesFiltersForm validationHapticsInvoicingMotion presetsNavigationNumber formatRelative timeRomanian locationsSpreadsheetText matchTonesUIProvideruseClipboarduseConsentuseControllableStateuseCooldownuseDebounceuseKeyboardInsetuseLocaleuseLongPressuseMediaControlsuseMediaQueryuseOverflowItemsusePersistedStateuseScrollEdgesuseScrollStateuseSelectionuseShortcutuseStickToBottom
GalleryTheme

Templates

Referral Page

Templates

Referral Page

Design
Product Tour PageRoadmap Page
Design
Live props
Appearance
design
alternate
tone
ctaTone
radius
Content
rank
reward
friendReward
Behavior
maxInvites
animateIn
locale
State
defaultFilter
defaultNote
Layout
showShare
showRewards
showInvite
showReferrals
showSteps
showLeaderboard
showTerms
showFaq
showCta
stepsLayout
ctaVariant
header
footer
Code
import { ReferralPage } from "@/components/templates/referral-page"

<ReferralPage />
  1. Home
  2. Templates
  3. Referral Page
Pro

Referral Page

v1.0.0·Added in 1.8.0

A refer-a-friend page: drawn gift cards, a copyable invite link with share buttons, email invites, reward milestones and referrals.

The hero rises in once on mount beside two drawn Acme gift cards in 3D (the friend's $20 card in front, your $20 credit behind) that tilt into place over a soft glow and straighten a little on hover, with the latest subscribed friend and the next milestone floating around them on wide screens. Copy link copies the personal invite link and turns into a check; Email, X, LinkedIn and WhatsApp open the real share URLs with a prefilled message, Copy message copies that message, and More opens the system share sheet where the browser has one. The checkout code copies on click. In Your rewards the earned amount rolls up when the panel scrolls into view and the milestone track (1 friend $20, 3 a month of Pro, 5 the hoodie, 10 a year of Business) fills up to your count, across on wide screens and down on phones, with reached, next and locked states. Invite by email takes a list of addresses as chips: Enter, comma, semicolon or space adds one, a pasted list splits into chips, Backspace edits the last one, and an invalid, duplicate, already invited or own address is refused with a message. The personal note and the To line update a drawn preview of the email your friend gets. Send invites spins while onInvite runs (or 900 ms without it), then the friends appear at the top of Your referrals as Invited, a toast confirms and a success line shows; a rejection shows an error and keeps the chips. Your referrals filters by status with pill tabs that show counts (arrow keys move between them), shows a table on wide screens and stacked rows on phones, and Resend on an invited friend spins, then reads Sent. An empty list shows a first-run state with a link to the form. How it works, this month's leaderboard with your own rank, the terms in short, the FAQ (one answer open at a time) and the closing band follow. Reduced motion keeps everything still.

Built with

The sections this page is made of. In the full-screen preview, hold Alt to outline each one on the page.

  • Marketing Sectionmarketing-section
  • Marketing Headermarketing-header
  • Marketing Footermarketing-footer
  • Steps Sectionsteps-section
  • FAQ Sectionfaq-section
  • CTA Sectioncta-section

Add to a project

npx wingo-ui@latest add referral-page

Pro item: the CLI needs a Pro account. See plans

Usage

// app/(app)/refer/page.tsx
"use client"

import Link from "next/link"
import { ReferralPage } from "@/components/templates/referral-page"

export default function ReferRoute() {
  return (
    <ReferralPage
      linkComponent={Link}
      user={{ name: "Ryan Cooper", email: "ryan@brightlane.co", link: "https://acme.com/r/ryan-cooper", code: "RYAN20" }}
      ctaTone="brand"
      onInvite={async (emails, note) => {
        const response = await fetch("/api/referrals/invite", { method: "POST", body: JSON.stringify({ emails, note }) })
        if (!response.ok) throw new Error("Could not send the invites")
      }}
    />
  )
}

Props

  • designdefault "classic"
    "classic" | "bold" | "minimal"

    The whole page's look. classic follows the layout props: a split hero with the gift cards on the right over a dotted glow; bold: a pill header, a giant stage title on a gradient mesh, rounder panels, step cards, FAQ cards, an image band and a wordmark footer; minimal: a transparent header, a centered stacked hero, no glow or floating chips, outlined flat panels, no gray bands and a simple footer. The *Props overrides still win.

  • userdefault "REFERRAL_USER"
    ReferralUser

    The signed-in person: { name, email, link, code }. The link fills the copy field and every share URL, the code shows under it and on the cards.

  • referralsdefault "REFERRAL_REFERRALS"
    Referral[]

    The starting list: { id, name?, email, status: "invited" | "signed-up" | "subscribed", date (ISO) }. Invites sent from the page are added on top. Counts drive the earned total and the milestones.

  • milestones
    ReferralMilestone[]

    Rewards by subscribed friends: { id, friends, reward, description, icon? }. Defaults to getReferralMilestones(amount), so the first one names your reward.

  • leadersdefault "REFERRAL_LEADERS"
    ReferralLeader[]

    This month's top referrers: { id, name, company, friends, earned (USD) }.

  • rankdefault 23
    number

    Your place on the leaderboard; past the listed leaders it shows as your own row under them.

  • steps
    StepsSectionItem[]

    How it works: { icon?, title, description, meta? }. Defaults to getReferralSteps(friendAmount, amount).

  • terms
    string[]

    The short version of the program terms. Defaults to getReferralTerms(amount).

  • faq
    FaqItem[]

    { question, answer } pairs about referrals. Defaults to getReferralFaq(friendAmount, amount).

  • labelsdefault "DEFAULT_REFERRAL_PAGE_LABELS"
    Partial<ReferralPageLabels>

    Every visible string; the ones with amounts or counts in them are functions.

  • hrefsdefault "DEFAULT_REFERRAL_PAGE_HREFS"
    Partial<ReferralPageHrefs>

    { workspace, rewards, invite, terms }: the header button, the in-page anchors and the full terms.

  • rewarddefault 20
    number

    What you earn per subscribed friend, in USD: the title, the cards, the earned total and the reward column.

  • friendRewarddefault 20
    number

    What your friend gets off their first month, in USD: the title, the friend's card and the email.

  • maxInvitesdefault 20
    number

    Emails per send; at the limit the chips field stops taking more.

  • defaultFilterdefault "all"
    "all" | "invited" | "signed-up" | "subscribed"

    The referrals filter on load.

  • defaultNotedefault ""
    string

    The personal note on load; empty shows the placeholder in the preview.

  • showSharedefault true
    boolean

    The share buttons under the invite link.

  • showRewardsdefault true
    boolean

    Your rewards: the earned total and the milestone track.

  • showInvitedefault true
    boolean

    Invite by email with the email preview.

  • showReferralsdefault true
    boolean

    Your referrals list.

  • showStepsdefault true
    boolean

    How it works.

  • showLeaderboarddefault true
    boolean

    This month's top referrers.

  • showTermsdefault true
    boolean

    The short terms card.

  • showFaqdefault true
    boolean

    The FAQ.

  • showCtadefault true
    boolean

    The closing call to action.

  • stepsLayoutdefault "horizontal"
    "horizontal" | "cards" | "vertical"

    How it works as a numbered row, numbered tiles or a timeline rail. Applies to the classic design.

  • ctaVariantdefault "inverted"
    "inverted" | "soft" | "split"

    The closing band: a solid band, a gray band, or copy beside the buttons on a raised panel. Applies to the classic design.

  • alternatedefault true
    boolean

    Gray bands on every other visible section. Applies to the classic and bold designs.

  • tonedefault "neutral"
    "neutral" | "brand" | "success" | "warning" | "danger" | "info"

    Accents across the page: the hero glow, the cards' sheen, the milestone fills and nodes, leaderboard bars, terms checks and step markers.

  • ctaTonedefault "neutral"
    "neutral" | "brand" | "success" | "warning" | "danger" | "info"

    Copy link, Send invites, the phone menu's button and the closing band; brand is the marketing orange.

  • radiusdefault "md"
    "none" | "sm" | "md" | "lg" | "full"

    The corners of the emails and note fields.

  • headerdefault true
    boolean

    The marketing header with Open Acme and your avatar; off inside a site layout.

  • footerdefault true
    boolean

    The marketing footer.

  • headerProps
    Partial<MarketingHeaderProps>

    Passed to MarketingHeader.

  • footerProps
    Partial<MarketingFooterProps>

    Passed to MarketingFooter.

  • stepsProps
    Partial<StepsSectionProps>

    Overrides for the StepsSection.

  • faqProps
    Partial<FaqSectionProps>

    Overrides for the FaqSection.

  • ctaProps
    Partial<CtaSectionProps>

    Overrides for the CtaSection.

  • onInvite
    (emails: string[], note: string) => (void | Promise<unknown>)

    Send invites. A promise keeps the button loading and a rejection shows an error with the chips kept. Without it the form waits 900 ms and toasts. Either way the friends then appear in Your referrals as Invited.

  • onResend
    (referral: Referral) => (void | Promise<unknown>)

    Resend on an invited friend; a promise keeps it loading. Without it: 900 ms and a toast.

  • onShare
    (channel: "email" | "x" | "linkedin" | "whatsapp" | "native") => void

    A share button was pressed; the share URL still opens.

  • onCopyLink
    (link: string) => void

    The invite link was copied.

  • toastOptionsdefault "{}"
    ToastOptions | false

    Options for the pretend send and resend toasts ({ toasterId, duration... }); false sends none. A Toaster must be mounted to see them.

  • animateIndefault true
    boolean

    The hero rises in once, the cards tilt into place and the earned total rolls up on view; false keeps the page still (thumbnails). Reduced motion always does.

  • localedefault "en-US"
    string

    Intl locale for the USD amounts, counters and dates.

  • linkComponentdefault "<a>"
    (props: LinkComponentProps) => ReactNode

    The router link for every in-site link on the page (next/link in an app). Share links stay plain anchors.

  • className
    string

    Classes for the root.

  • classNames
    Partial<Record<ReferralPageSlot, string>>

    Classes for header, hero, title, link, share, cards, rewards, milestones, invite, form, preview, referrals, list, steps, leaderboard, terms, faq, cta and footer.

Parts

  • REFERRAL_PAGE_SAMPLE

    constant

    All the sample content in one object: user, referrals, milestones, leaders, steps, terms and faq.

  • REFERRAL_USER

    constant

    Ryan Cooper with the link acme.com/r/ryan-cooper and the code RYAN20.

  • REFERRAL_REFERRALS

    constant

    Eight friends: three subscribed, two signed up and three invited.

  • REFERRAL_MILESTONES

    constant

    1 friend $20 credit, 3 a month of Pro, 5 the Acme hoodie, 10 a year of Business.

  • REFERRAL_LEADERS

    constant

    This month's five top referrers.

  • REFERRAL_STEPS

    constant

    Share your link, your friend gets $20, you get $20.

  • REFERRAL_TERMS

    constant

    Five lines of program terms.

  • REFERRAL_FAQ

    constant

    Six questions about timing, the friend's reward, limits, teammates, missing rewards and credit.

  • getReferralMilestones

    function

    (amount = "$20") => ReferralMilestone[]: the sample milestones with your formatted reward in the first one.

  • getReferralSteps

    function

    (friendAmount = "$20", amount = "$20") => StepsSectionItem[]: the three steps with both amounts.

  • getReferralTerms

    function

    (amount = "$20") => string[]: the short terms.

  • getReferralFaq

    function

    (friendAmount = "$20", amount = "$20") => FaqItem[]: the sample questions with both amounts.

  • DEFAULT_REFERRAL_PAGE_LABELS

    constant

    The English strings.

  • DEFAULT_REFERRAL_PAGE_HREFS

    constant

    The default link targets.

  • REFERRAL_PAGE_DESIGNS

    constant

    The design names, classic first: ["classic", "bold", "minimal"].

  • ReferralPageProps

    type

    Props of ReferralPage.

  • ReferralPageDesign

    type

    "classic" | "bold" | "minimal".

  • ReferralFilter

    type

    "all" | "invited" | "signed-up" | "subscribed".

  • Referral

    type

    One invited friend.

  • ReferralStatus

    type

    "invited" | "signed-up" | "subscribed".

  • ReferralUser

    type

    The signed-in person sharing their link.

  • ReferralMilestone

    type

    A reward unlocked by a number of subscribed friends.

  • ReferralLeader

    type

    One leaderboard row.

  • ReferralShareChannel

    type

    "email" | "x" | "linkedin" | "whatsapp" | "native".

  • ReferralPageLabels

    type

    The strings labels can override.

  • ReferralPageHrefs

    type

    The link targets hrefs can override.

Examples

Open

Bold design

design="bold": a giant stage title on a gradient mesh, rounder panels, step cards, FAQ cards and a wordmark footer.

Open

Minimal design

design="minimal": a transparent header, a centered hero, outlined panels, no gray bands and a simple footer.

Open

Give $50, get $25 in brand orange

friendReward 50 and reward 25 with tone and ctaTone brand: the title, cards, email and totals follow the amounts.

Open

First visit, nobody invited yet

An empty referrals list: no earned total, an empty milestone track and a first-run state that points to the form.

Open

Mail service down

An onInvite that rejects: add a few emails and send to see the error while the chips stay in place.

Dependencies

lucide-reactmotionmarketing-sectionmarketing-headermarketing-footersteps-sectionfaq-sectioncta-sectionanimated-counteravatarbadgebuttoncopy-buttonempty-statefieldtabstag-inputtextareatoastmotionnavigationtonesui-config

Files

  • components/templates/referral-page.tsx
  • components/templates/referral-page-data.ts

See also

Affiliate PageStartups PagePricing PageTag InputCopy Button
PreviousProduct Tour PageNext Roadmap Page