We use tracking cookies to understand how you use the product and help us improve it. For more information on how we store cookies, read our  privacy policy.

TotalBuyers.tsx

A social proof component that displays customer avatars, star ratings, and total buyer count from Stripe orders.

The TotalBuyers component fetches real customer data from Stripe and displays it as social proof with avatars, star ratings, and buyer count. It's commonly used in hero sections to build trust.

Props

TotalBuyers PropsTypeDefault
text
string
-

Usage

Basic Implementation

@/app/(base)/page.tsx
import { TotalBuyers } from '@/components/TotalBuyers';

export default function HomePage() {
  return (
    <section>
      <h1>Welcome to Our Product</h1>
      <TotalBuyers text="customers already using this" />
    </section>
  );
}

In Hero Section

@/components/Hero.tsx
import { TotalBuyers } from '@/components/TotalBuyers';
import locale from '@/locales/en.json';

export function Hero() {
  const heroLocale = locale?.homePage?.heroSection;

  return (
    <section className="flex flex-col items-center gap-8">
      <h1>{heroLocale?.title?.firstLine}</h1>
      <p>{heroLocale?.description}</p>
      <TotalBuyers text={heroLocale?.buyersText} />
    </section>
  );
}

Features

  • Real Data: Fetches actual customer count from Stripe orders
  • Customer Avatars: Displays profile images from recent buyers
  • Star Rating: Shows 5-star rating visualization
  • Responsive Design: Adapts layout for mobile and desktop
  • Automatic Fallback: Returns null if no orders exist
  • Image Optimization: Uses Next.js Image with fallback support

Implementation Details

Data Fetching

The component uses the getOrders function to fetch Stripe data:

@/lib/stripe/getOrders.ts
export async function getOrders() {
  // Fetches orders from Stripe
  // Returns { totalBuyersCount, imageUrls }
}

Returns:

  • totalBuyersCount - Number of unique customers
  • imageUrls - Array of customer profile image URLs

Avatar Display

Customer avatars are displayed with overlapping effect:

Avatar Styling
<div className="flex items-center -space-x-2">
  {imageUrls?.map((img, i) => (
    <ImageWithFallback
      src={img}
      alt={`User Mockup ${i}`}
      width={84}
      height={84}
      className="size-12 object-cover rounded-full ring-4 ring-surface"
      key={`user-${i}`}
    />
  ))}
</div>

The -space-x-2 class creates the overlapping effect.

Star Rating

The component renders 5 filled star icons:

Star Rating
<div className="flex items-center gap-1">
  <SvgFinder icon="Star" className="fill-yellow-400 stroke-yellow-400" />
  <SvgFinder icon="Star" className="fill-yellow-400 stroke-yellow-400" />
  <SvgFinder icon="Star" className="fill-yellow-400 stroke-yellow-400" />
  <SvgFinder icon="Star" className="fill-yellow-400 stroke-yellow-400" />
  <SvgFinder icon="Star" className="fill-yellow-400 stroke-yellow-400" />
</div>

Customization

Custom Text

Pass different text for various contexts:

Different Contexts
{/* Hero section */}
<TotalBuyers text="happy customers" />

{/* Pricing page */}
<TotalBuyers text="businesses trust us" />

{/* Testimonials section */}
<TotalBuyers text="5-star reviews" />

Styling Avatars

Customize avatar appearance:

Custom Avatar Styling
<ImageWithFallback
  src={img}
  alt={`User ${i}`}
  width={84}
  height={84}
  className="size-16 object-cover rounded-full ring-2 ring-primary"
/>

Changing Star Color

Modify star icon colors:

Custom Star Colors
<SvgFinder icon="Star" className="fill-blue-400 stroke-blue-400" />

Locale Configuration

Configure the text in locales/en.json:

@/locales/en.json
{
  "homePage": {
    "heroSection": {
      "buyersText": "customers already using this"
    }
  }
}

Conditional Rendering

The component returns null if no orders exist:

Conditional Rendering
if (!orders) {
  return null;
}

This prevents displaying "0 customers" on new installations.

Performance

  • Server Component: Fetches data on the server for optimal performance
  • Image Optimization: Uses Next.js Image with priority flag
  • Quality Setting: Images loaded at 80% quality for faster loading

Styling

The component uses Tailwind CSS with responsive design:

  • Desktop: Horizontal layout with avatars and text side-by-side
  • Mobile: Vertical layout with centered content (max-md:flex-col max-md:items-center)
  • Avatar rings: ring-4 ring-surface creates white border effect
  • Text color: text-neutral-foreground for secondary text

How is this guide ?

Last updated on