Testimonials

Testimonials sections showcase positive feedback and reviews from customers or users. They help build trust and credibility for your product or service, encouraging potential customers to make a purchase or take action.

Testimonials Marquee

Installation

npm install framer-motion lucide-react
pnpm install framer-motion lucide-react
yarn add framer-motion lucide-react
bun add framer-motion lucide-react

Copy and paste the following code into your project.

components/ui/marquee.tsx

marquee.tsx
import { cn } from "@/lib/utils";
import { ComponentPropsWithoutRef } from "react";

interface MarqueeProps extends ComponentPropsWithoutRef<"div"> {
  /**
   * Optional CSS class name to apply custom styles
   */
  className?: string;
  /**
   * Whether to reverse the animation direction
   * @default false
   */
  reverse?: boolean;
  /**
   * Whether to pause the animation on hover
   * @default false
   */
  pauseOnHover?: boolean;
  /**
   * Content to be displayed in the marquee
   */
  children: React.ReactNode;
  /**
   * Whether to animate vertically instead of horizontally
   * @default false
   */
  vertical?: boolean;
  /**
   * Number of times to repeat the content
   * @default 4
   */
  repeat?: number;
}

export function Marquee({
  className,
  reverse = false,
  pauseOnHover = false,
  children,
  vertical = false,
  repeat = 4,
  ...props
}: MarqueeProps) {
  return (
    <div
      {...props}
      className={cn(
        "group flex overflow-hidden p-2 [--duration:40s] [--gap:1rem] [gap:var(--gap)]",
        {
          "flex-row": !vertical,
          "flex-col": vertical,
        },
        className,
      )}
    >
      {Array(repeat)
        .fill(0)
        .map((_, i) => (
          <div
            key={i}
            className={cn("flex shrink-0 justify-around [gap:var(--gap)]", {
              "animate-marquee flex-row": !vertical,
              "animate-marquee-vertical flex-col": vertical,
              "group-hover:[animation-play-state:paused]": pauseOnHover,
              "[animation-direction:reverse]": reverse,
            })}
          >
            {children}
          </div>
        ))}
    </div>
  );
}

Update tailwind.config.ts

/** @type {import('tailwindcss').Config} */
module.exports = {
  theme: {
    extend: {
      animation: {
        marquee: "marquee var(--duration) linear infinite", 
        "marquee-vertical": "marquee-vertical var(--duration) linear infinite", 
      }, 
      keyframes: { 
        marquee: { 
          from: { transform: "translateX(0)" }, 
          to: { transform: "translateX(calc(-100% - var(--gap)))" }, 
        }, 
        "marquee-vertical": { 
          from: { transform: "translateY(0)" }, 
          to: { transform: "translateY(calc(-100% - var(--gap)))" }, 
        }, 
      }, 
    },
  },
};

Props

Highlight Props

PropTypeDefault
children?
React.ReactNode
undefined
className?
string
undefined

TestimonialCard Props

PropTypeDefault
name?
string
undefined
role?
string
undefined
img?
string
undefined
description?
React.ReactNode
undefined
className?
string
undefined

Last updated on