Docs
Customer Logos Wall

Customer Logos Wall

A clean grid layout for displaying customer and partner logos. Features flexible columns, grayscale effects, and smooth hover animations.

Trusted by industry leaders

Join thousands of companies that rely on our platform

And many more companies worldwide

Powering the best teams

From startups to enterprises

And many more companies worldwide

Our partners

Working with the best in the industry

And many more companies worldwide

Trusted by industry leaders

Join thousands of companies that rely on our platform

And many more companies worldwide

Installation

Install dependencies

npm install framer-motion react-icons

Copy and paste the following code into your project.

"use client";
 
import { motion } from "framer-motion";
import { createElement } from "react";
 
interface Logo {
  id: string;
  name: string;
  logo?: string;
  icon?: React.ElementType;
  url?: string;
}
 
interface CustomerLogosWallProps {
  title?: string;
  description?: string;
  logos: Logo[];
  columns?: 3 | 4 | 5 | 6;
  grayscale?: boolean;
  className?: string;
}
 
export function CustomerLogosWall({
  title = "Trusted by industry leaders",
  description = "Join thousands of companies that rely on our platform",
  logos,
  columns = 6,
  grayscale = true,
  className = "",
}: CustomerLogosWallProps) {
  const gridCols = {
    3: "grid-cols-2 sm:grid-cols-3",
    4: "grid-cols-2 sm:grid-cols-3 md:grid-cols-4",
    5: "grid-cols-2 sm:grid-cols-3 md:grid-cols-5",
    6: "grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-6",
  }[columns];
 
  return (
    <section className={`w-full bg-white py-16 dark:bg-black ${className}`}>
      <div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
        {/* Header */}
        {(title || description) && (
          <div className="mb-12 text-center">
            {title && (
              <h2 className="mb-3 text-2xl font-bold text-zinc-900 dark:text-white sm:text-3xl">
                {title}
              </h2>
            )}
            {description && (
              <p className="text-base text-zinc-600 dark:text-zinc-400">
                {description}
              </p>
            )}
          </div>
        )}
 
        {/* Logos Grid */}
        <div className={`grid gap-8 ${gridCols}`}>
          {logos.map((logo, index) => (
            <motion.div
              key={logo.id}
              initial={{ opacity: 0, y: 20 }}
              animate={{ opacity: 1, y: 0 }}
              transition={{ delay: index * 0.05, duration: 0.4 }}
              className="group relative flex items-center justify-center"
            >
              {logo.url ? (
                <a
                  href={logo.url}
                  target="_blank"
                  rel="noopener noreferrer"
                  className="flex h-20 w-full items-center justify-center rounded-xl border border-zinc-200 bg-white p-6 transition-all duration-300 hover:border-zinc-300 hover:shadow-md dark:border-zinc-800 dark:bg-zinc-950 dark:hover:border-zinc-700"
                >
                  {logo.icon ? (
                    createElement(logo.icon, {
                      className: `h-10 w-10 transition-all duration-300 ${
                        grayscale
                          ? "grayscale opacity-60 group-hover:grayscale-0 group-hover:opacity-100"
                          : "opacity-80 group-hover:opacity-100"
                      }`,
                    })
                  ) : (
                    <img
                      src={logo.logo}
                      alt={logo.name}
                      className={`h-full w-full object-contain transition-all duration-300 ${
                        grayscale
                          ? "grayscale opacity-60 group-hover:grayscale-0 group-hover:opacity-100"
                          : "opacity-80 group-hover:opacity-100"
                      }`}
                    />
                  )}
                </a>
              ) : (
                <div className="flex h-20 w-full items-center justify-center rounded-xl border border-zinc-200 bg-white p-6 transition-all duration-300 hover:border-zinc-300 hover:shadow-md dark:border-zinc-800 dark:bg-zinc-950 dark:hover:border-zinc-700">
                  {logo.icon ? (
                    createElement(logo.icon, {
                      className: `h-10 w-10 transition-all duration-300 ${
                        grayscale
                          ? "grayscale opacity-60 group-hover:grayscale-0 group-hover:opacity-100"
                          : "opacity-80 group-hover:opacity-100"
                      }`,
                    })
                  ) : (
                    <img
                      src={logo.logo}
                      alt={logo.name}
                      className={`h-full w-full object-contain transition-all duration-300 ${
                        grayscale
                          ? "grayscale opacity-60 group-hover:grayscale-0 group-hover:opacity-100"
                          : "opacity-80 group-hover:opacity-100"
                      }`}
                    />
                  )}
                </div>
              )}
            </motion.div>
          ))}
        </div>
 
        {/* Bottom Text */}
        <div className="mt-12 text-center">
          <p className="text-sm text-zinc-500 dark:text-zinc-500">
            And many more companies worldwide
          </p>
        </div>
      </div>
    </section>
  );
}

Features

  • Flexible columns - Choose 3, 4, 5, or 6 column layouts
  • Grayscale effect - Optional grayscale with color on hover
  • Hover animations - Smooth opacity and shadow transitions
  • Clickable logos - Optional links to company websites
  • Responsive grid - Adapts to all screen sizes
  • Light/dark mode - Full theme support
  • Staggered animation - Sequential logo appearance
  • Clean borders - Subtle card borders
  • TypeScript support - Full type safety

Usage

import CustomerLogosWall from "@/components/ui/customer-logos-wall";
import {SiVercel, SiNextdotjs, SiStripe} from "react-icons/si";
 
const logos = [
  {
    id: "1",
    name: "Vercel",
    icon: SiVercel,
    url: "https://vercel.com",
  },
  {
    id: "2",
    name: "Next.js",
    icon: SiNextdotjs,
    url: "https://nextjs.org",
  },
  // ... more logos
];
 
export default function Page() {
  return <CustomerLogosWall logos={logos} />;
}

With Image URLs

const logos = [
  {
    id: "1",
    name: "Company Name",
    logo: "/logos/company.png",
    url: "https://company.com",
  },
  // ... more logos
];

4 Column Layout

<CustomerLogosWall logos={logos} columns={4} />

Without Grayscale

<CustomerLogosWall logos={logos} grayscale={false} />

With Custom Title

<CustomerLogosWall
  title="Trusted by industry leaders"
  description="Join thousands of companies worldwide"
  logos={logos}
/>

Without Header

<CustomerLogosWall title="" description="" logos={logos} />

Props

CustomerLogosWallProps

PropTypeDefaultDescription
logosLogo[]RequiredArray of logo objects
titlestring"Trusted by industry leaders"Section title
descriptionstring"Join thousands of companies..."Section description
columns3 | 4 | 5 | 66Number of columns
grayscalebooleantrueApply grayscale effect
classNamestring""Additional CSS classes
PropTypeRequiredDescription
idstringYesUnique identifier
namestringYesCompany name (for alt text)
logostringNo*Logo image URL
iconReact.ElementTypeNo*React Icon component
urlstringNoCompany website URL

*Either logo or icon must be provided

TypeScript Interface

interface Logo {
  id: string;
  name: string;
  logo?: string; // Image URL
  icon?: React.ElementType; // React Icon component
  url?: string;
}
 
interface CustomerLogosWallProps {
  title?: string;
  description?: string;
  logos: Logo[];
  columns?: 3 | 4 | 5 | 6;
  grayscale?: boolean;
  className?: string;
}

Use Cases

Perfect for:

  • SaaS landing pages
  • Homepage social proof
  • About pages
  • Partner pages
  • Case study sections
  • Footer sections
  • Investor pages
  • Press pages

Logo Sources

The easiest way to add logos is using react-icons:

npm install react-icons

Simple Icons (Si) - 2000+ brand logos:

import {SiVercel, SiNextdotjs, SiStripe, SiGithub} from "react-icons/si";

Font Awesome Brands (Fa) - Popular brands:

import {FaApple, FaMicrosoft, FaGoogle} from "react-icons/fa";

Browse all icons: react-icons.github.io

Image URLs

If using custom logos:

Recommended Specs:

  • Format: PNG or SVG
  • Background: Transparent
  • Size: 200x200px minimum
  • Color: Full color (grayscale applied by component)
  • Padding: Include some padding in the image itself

Tools:

Customization

Change Card Height

// Modify the card height
className = "flex h-24 w-full items-center..."; // Changed from h-20 to h-24

Change Gap Between Logos

// Modify the grid gap
<div className={`grid gap-12 ${gridCols}`}> {/* Changed from gap-8 to gap-12 */}

Remove Borders

// Remove border classes
className =
  "flex h-20 w-full items-center justify-center rounded-xl bg-white p-6...";
// Removed: border border-zinc-200

Add Background Pattern

<section className="... relative">
  <div className="absolute inset-0 bg-[linear-gradient(to_right,#80808012_1px,transparent_1px),linear-gradient(to_bottom,#80808012_1px,transparent_1px)] bg-[size:24px_24px]" />
  <div className="relative">{/* Content */}</div>
</section>

Custom Hover Colors

// Change hover border color
className = "... hover:border-blue-300 dark:hover:border-blue-700";

Add Logo Tooltips

<div className="group relative...">
  <img ... />
  <div className="absolute -top-10 left-1/2 -translate-x-1/2 rounded bg-zinc-900 px-2 py-1 text-xs text-white opacity-0 transition-opacity group-hover:opacity-100">
    {logo.name}
  </div>
</div>

Infinite Scroll Version

// For a marquee/infinite scroll effect, use the infinite-scroll component
// Or implement with CSS animations
<div className="overflow-hidden">
  <div className="animate-scroll flex gap-8">
    {logos.map(logo => (...))}
    {logos.map(logo => (...))} {/* Duplicate for seamless loop */}
  </div>
</div>

Common Patterns

With Section Divider

<CustomerLogosWall
  logos={logos}
  className="border-t border-zinc-200 dark:border-zinc-800"
/>

Compact Version

<CustomerLogosWall
  title=""
  description=""
  logos={logos}
  columns={6}
  className="py-8" // Reduced padding
/>
<CustomerLogosWall
  title="Featured Partners"
  description="Strategic partnerships that drive innovation"
  logos={featuredLogos}
  columns={4}
  grayscale={false}
/>
<CustomerLogosWall
  title="As seen in"
  logos={pressLogos}
  columns={5}
  className="bg-zinc-50 dark:bg-zinc-900"
/>