Back to library
sections
Testimonials Columns
Vertically scrolling testimonial columns with looping motion. Great for landing page social proof sections.
Inspired by S. Shahaider · View source
Preview
This platform completely changed how our team ships. Everything just clicks.
Alex Rivera
Product Lead
The onboarding was so smooth. I had our first workflow live within an hour.
Priya Shah
Founder, Northloop
Support is fast, docs are clear, and the API feels designed by people who care.
Marcus Chen
Staff Engineer
We replaced three separate tools with this. Our stack finally feels sane.
Sara Okonkwo
Head of Ops
Beautiful defaults, endless flexibility. Exactly what I look for in a tool.
Luca Bianchi
Design Engineer
This platform completely changed how our team ships. Everything just clicks.
Alex Rivera
Product Lead
The onboarding was so smooth. I had our first workflow live within an hour.
Priya Shah
Founder, Northloop
Support is fast, docs are clear, and the API feels designed by people who care.
Marcus Chen
Staff Engineer
We replaced three separate tools with this. Our stack finally feels sane.
Sara Okonkwo
Head of Ops
Beautiful defaults, endless flexibility. Exactly what I look for in a tool.
Luca Bianchi
Design Engineer
Beautiful defaults, endless flexibility. Exactly what I look for in a tool.
Luca Bianchi
Design Engineer
We replaced three separate tools with this. Our stack finally feels sane.
Sara Okonkwo
Head of Ops
Support is fast, docs are clear, and the API feels designed by people who care.
Marcus Chen
Staff Engineer
The onboarding was so smooth. I had our first workflow live within an hour.
Priya Shah
Founder, Northloop
This platform completely changed how our team ships. Everything just clicks.
Alex Rivera
Product Lead
Beautiful defaults, endless flexibility. Exactly what I look for in a tool.
Luca Bianchi
Design Engineer
We replaced three separate tools with this. Our stack finally feels sane.
Sara Okonkwo
Head of Ops
Support is fast, docs are clear, and the API feels designed by people who care.
Marcus Chen
Staff Engineer
The onboarding was so smooth. I had our first workflow live within an hour.
Priya Shah
Founder, Northloop
This platform completely changed how our team ships. Everything just clicks.
Alex Rivera
Product Lead
This platform completely changed how our team ships. Everything just clicks.
Alex Rivera
Product Lead
The onboarding was so smooth. I had our first workflow live within an hour.
Priya Shah
Founder, Northloop
Support is fast, docs are clear, and the API feels designed by people who care.
Marcus Chen
Staff Engineer
We replaced three separate tools with this. Our stack finally feels sane.
Sara Okonkwo
Head of Ops
Beautiful defaults, endless flexibility. Exactly what I look for in a tool.
Luca Bianchi
Design Engineer
This platform completely changed how our team ships. Everything just clicks.
Alex Rivera
Product Lead
The onboarding was so smooth. I had our first workflow live within an hour.
Priya Shah
Founder, Northloop
Support is fast, docs are clear, and the API feels designed by people who care.
Marcus Chen
Staff Engineer
We replaced three separate tools with this. Our stack finally feels sane.
Sara Okonkwo
Head of Ops
Beautiful defaults, endless flexibility. Exactly what I look for in a tool.
Luca Bianchi
Design Engineer
Copy for AI
Copy for Lovable is the fastest way to move this component into another Lovable project — it copies the full prompt with dependencies, files, and a usage example. Copy all files gives you the raw source if you want to paste it manually.
Installation
npx shadcn@latest add https://21st.dev/r/sshahaider/testimonials-columns-1Paste into a terminal — or paste into a Lovable chat and I'll run it for you.
Source files
components/ui/testimonials-columns.tsx
"use client";
import React from "react";
import { motion } from "motion/react";
export type Testimonial = {
text: string;
image: string;
name: string;
role: string;
};
export const TestimonialsColumn = (props: {
className?: string;
testimonials: Testimonial[];
duration?: number;
}) => {
return (
<div className={props.className}>
<motion.div
animate={{ translateY: "-50%" }}
transition={{
duration: props.duration || 10,
repeat: Infinity,
ease: "linear",
repeatType: "loop",
}}
className="flex flex-col gap-6 pb-6 bg-background"
>
{[
...new Array(2).fill(0).map((_, index) => (
<React.Fragment key={index}>
{props.testimonials.map(({ text, image, name, role }, i) => (
<div
className="p-10 rounded-3xl border shadow-lg shadow-primary/10 max-w-xs w-full"
key={i}
>
<div>{text}</div>
<div className="flex items-center gap-2 mt-5">
<img
width={40}
height={40}
src={image}
alt={name}
className="h-10 w-10 rounded-full"
/>
<div className="flex flex-col">
<div className="font-medium tracking-tight leading-5">{name}</div>
<div className="leading-5 opacity-60 tracking-tight">{role}</div>
</div>
</div>
</div>
))}
</React.Fragment>
)),
]}
</motion.div>
</div>
);
};Dependencies
motion