Social proof toast
ProA stack of social proof notifications for landing and pricing pages, where recent trials, upgrades and verified purchases from people and companies arrive every few seconds. The stack pauses and fans out on hover, and visitors can dismiss any toast.
Live · keyboard ready
- Showing recent trials, purchases or upgrades on a landing or pricing page.
- A live activity feed for a launch or waitlist page (people joining, teams upgrading).
- Highlighting verified purchases from known companies near a checkout CTA.
- System feedback after a user action (saved, copied, failed): use toast or undo-toast.
- Inside a signed in product where activity is not marketing: use an activity feed list.
- When you do not have real events to show; fabricated social proof erodes trust.
Installation
Pro source and install commands unlock with a Pro plan.
example.tsx
import { SocialProofToast } from "@/components/arc/social-proof-toast/social-proof-toast";import type { SocialProofEvent } from "@/components/arc/social-proof-toast/social-proof-toast";import { LinearMark } from "@/components/arc/social-proof-toast/social-proof-toast-marks"; const events: SocialProofEvent[] = [ { id: "1", name: "Sofia", action: "started a Pro trial", meta: "Madrid", time: new Date(Date.now() - 2 * 60_000), avatar: "/people/sofia.jpg" }, { id: "2", name: "Linear", action: "upgraded to Business", meta: "48 seats", time: Date.now() - 4 * 60_000, logo: <LinearMark />, verified: "Verified by Stripe" },]; export function Landing() { return <SocialProofToast events={events} position="bottom-left" limit={6} onShow={event => console.log("shown", event.id)} />;}API reference
2 parts. The first is the root.
SocialProofToast
Stacked social proof notifications for a landing or pricing page. Toasts cycle on an interval, pause and fan out on hover or focus, and can be dismissed. With no props it plays a sample SaaS feed.
PropTypeDefaultDescription
eventsSocialProofEvent[]sampleSocialProofEventsThe feed, oldest first. Each event is { id, name, action, meta?, time?, avatar?, logo?, verified? }. A Date or timestamp time renders as relative time; a string renders as is.intervalnumber4000Milliseconds between toasts. The countdown keeps its remaining time across hover and focus pauses.initialDelaynumber800Milliseconds before the first toast.maxVisiblenumber3How many toasts stack at once. Older ones fade out from the back.prefillnumber0How many toasts already show on mount, without an entrance. Useful for previews and screenshots.position"inline" | "bottom-left" | "bottom-right" | "top-left" | "top-right""inline"Inline sits in the layout. The corners pin the stack to the viewport, 24px from the edges (16px and full width on phones). Top positions stack downward.expandOnHoverbooleantrueFans the stack out while it is hovered or holds focus.loopbooleantrueStarts the feed over when it ends. False stops after the last event.limitnumber–Stops after this many toasts in a session, so the page stays calm.pausedbooleanfalsePauses the cycle from outside, for example while a modal or cookie banner is open.onShow(event: SocialProofEvent) => void–Called each time a toast appears, for impression tracking.onDismiss(event: SocialProofEvent) => void–Called when a visitor dismisses a toast.onSelect(event: SocialProofEvent) => void–Makes each toast a button, for example to open pricing or a customer story.labelstring"Recent activity"Accessible name of the region.classNamestring–Class on the root region.SocialProofEvent
One entry in the feed.
PropTypeDefaultDescription
idRequiredstring–Stable id, used for keys and callbacks.nameRequiredstring–A first name or a company, shown in medium weight.actionRequiredstring–What they did, read after the name: "started a Pro trial".metastring–Short context before the time, such as a city or a seat count.timeDate | number | string–When it happened. Dates render as Just now, 4 min ago, 2 h ago.avatarstring–Portrait URL for a person.logoReactNode–A company mark drawn in currentColor, rendered at 18px in the round slot when there is no avatar. Initials show when neither is set.verifiedboolean | string–Shows a check badge with a label. True reads Verified; pass a string such as Verified by Stripe.- Tab
- Moves to the dismiss button of each visible toast. Focus inside the stack pauses it and fans it out.
- EnterorSpace
- Dismisses the focused toast, or selects it when onSelect is set.
- Escape
- Dismisses the focused toast, or the front one. Focus moves to the next toast.
- The stack is a labelled region (Recent activity). New toasts are not announced, so screen reader users are not interrupted every few seconds; dismissals are confirmed in a polite status.
- Each dismiss button names the toast it closes, such as Dismiss: Sofia started a Pro trial.
- Toasts behind the stack limit are aria-hidden and inert. Hover and keyboard focus both pause the cycle, so nothing moves while someone reads or acts.
- The verified state is an icon plus a text label, never color alone. Portraits use empty alt text because the name is in the sentence.
- A new toast rises 16px and fades in at the front while the others step back 10px and scale down 5% each. Every move uses a bounce free spring (visual duration 0.24s); content of covered toasts fades out in 160ms so text never overlaps.
- Hover or focus fans the stack out with the same spring; dismissing fades and slightly shrinks the toast in 160ms and the rest close the gap.
- Toasts have a fixed 64px height, so nothing resizes between states.
- Reduced motion keeps the stack and the cycle but drops travel: toasts only fade.
- The cycle pauses off screen (IntersectionObserver) and in background tabs.
- 360px wide in a corner, 24px from the edges. Below 480px the stack spans the width with 16px gutters.
- Text truncates with an ellipsis on one line per row, so toast height never changes.
- On touch screens the dismiss button is always visible; on pointer devices it appears on hover or keyboard focus.
- At most maxVisible + 1 toasts are mounted. Animations are transform and opacity only.
- One timer drives the cycle and stops while paused, off screen, or in a hidden tab.
Notes for AI
Give your coding assistant the Markdown reference instead of screenshots.
- Use for social proof on marketing, pricing and checkout pages. Feed it real, recent events from your billing or analytics backend; do not invent activity.
- Keep it calm: interval 4000 to 8000ms, limit around 5 to 8 per session, and pause it while modals or cookie banners are open via paused.
- For one-off app notifications use toast or toast-stack instead. Marks should be mono and use currentColor so they follow the theme.
- position="inline" is for docs and previews; on a real page use a corner position.
The full library index for assistants is at /llms.txt.