About
A marquee component continuously scrolls text, images, or videos in an infinite loop, with customizable speed, direction, and responsive design for engaging displays.
Built with React and Tailwind. Copy the prompt and paste it into Claude Code, Cursor or Lovable: your agent adds 3D Testimonails to your project and fits it to your theme.
Code
How 3D Testimonails is used: the demo's code. The component's own source comes with a free account.
Usage.tsx
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
import { Card, CardContent } from '@/components/ui/card';
import { Marquee } from '@/components/ui/3d-testimonails';
// Unique reviews data
const testimonials = [
{
name: 'Ava Green',
username: '@ava',
body: 'Cascade AI made my workflow 10x faster!',
img: 'https://cdn.21st.dev/assets/mirror/55/55cf6231499bcdc496f15ff1d28d4170ac9b99e9279495caa44fca70886d8b2e.jpg',
country: '🇦🇺 Australia',
},
{
name: 'Ana Miller',
username: '@ana',
body: 'Vertical marquee is a game changer!',
img: 'https://cdn.21st.dev/assets/mirror/f0/f07b84f12ef125cbb837a7bd64da401992f5f62bd55fee10d01cd3dcc8abae80.jpg',
country: '🇩🇪 Germany',
},
{
name: 'Mateo Rossi',
username: '@mat',
body: 'Animations are buttery smooth!',
img: 'https://cdn.21st.dev/assets/mirror/7c/7c0d2aa99715b15c218385f5679347782843c02f939d8eee6f9cb1cad6ba6ed0.jpg',
country: '🇮🇹 Italy',
},
{
name: 'Maya Patel',
username: '@maya',
body: 'Setup was a breeze!',
img: 'https://cdn.21st.dev/assets/mirror/f8/f8f2ddc445b6b2318430260bdebb665c9415865827230565aa42f57c9c794baf.jpg',
country: '🇮🇳 India',
},
{
name: 'Noah Smith',
username: '@noah',
body: 'Best marquee component!',
img: 'https://cdn.21st.dev/assets/mirror/ae/ae1d49872fdd6f8d9aa933f6ca8bce8cb1ba7e87dfb9d2926661184cb7bfe26d.jpg',
country: '🇺🇸 USA',
},
{
name: 'Lucas Stone',
username: '@luc',
body: 'Very customizable and smooth.',
img: 'https://cdn.21st.dev/assets/mirror/9a/9aac54d62e727561f6958213b8a3649230a3bba61ba5ddf63c69d3c6e4aecb0a.jpg',
country: '🇫🇷 France',
},
{
name: 'Haruto Sato',
username: '@haru',
body: 'Impressive performance on mobile!',
img: 'https://cdn.21st.dev/assets/mirror/e5/e55f3cdab57eb4084f7006cfe9f7f047e638e1b257a53498aaed14b83087152a.jpg',
country: '🇯🇵 Japan',
},
{
name: 'Emma Lee',
username: '@emma',
body: 'Love the pause on hover feature!',
img: 'https://cdn.21st.dev/assets/mirror/03/03410c155320ba33ecb8d798807c6c9610f33b2b2acdd4ed961a68185806df79.jpg',
country: '🇨🇦 Canada',
},
{
name: 'Carlos Ray',
username: '@carl',
body: 'Great for testimonials and logos.',
img: 'https://cdn.21st.dev/assets/mirror/b5/b58616f0d669595c9a42d60a0b9803364c9859f1c3db93a5e3dc408b603e03e8.jpg',
country: '🇪🇸 Spain',
},
];
function TestimonialCard({ img, name, username, body, country }: (typeof testimonials)[number]) {
return (
<Card className="w-50">
<CardContent>
<div className="flex items-center gap-2.5">
<Avatar className="size-9">
<AvatarImage src={img} alt="@reui_io" />
<AvatarFallback>{name[0]}</AvatarFallback>
</Avatar>
<div className="flex flex-col">
<figcaption className="text-sm font-medium text-foreground flex items-center gap-1">
{name} <span className="text-xs">{country}</span>
</figcaption>
<p className="text-xs font-medium text-muted-foreground">{username}</p>
</div>
</div>
<blockquote className="mt-3 text-sm text-econdary-foreground">{body}</blockquote>
</CardContent>
</Card>
);
}
export default function DemoOne() {
return (
<div className="border border-border rounded-lg relative flex h-96 w-full max-w-[800px] flex-row items-center justify-center overflow-hidden gap-1.5 [perspective:300px]">
<div
className="flex flex-row items-center gap-4"
style={{
transform:
'translateX(-100px) translateY(0px) translateZ(-100px) rotateX(20deg) rotateY(-10deg) rotateZ(20deg)',
}}
>
{/* Vertical Marquee (downwards) */}
<Marquee vertical pauseOnHover repeat={3} className="[--duration:40s]">
{testimonials.map((review) => (
<TestimonialCard key={review.username} {...review} />
))}
</Marquee>
{/* Vertical Marquee (upwards) */}
<Marquee vertical pauseOnHover reverse repeat={3} className="[--duration:40s]">
{testimonials.map((review) => (
<TestimonialCard key={review.username} {...review} />
))}
</Marquee>
{/* Vertical Marquee (upwards) */}
<Marquee vertical pauseOnHover repeat={3} className="[--duration:40s]">
{testimonials.map((review) => (
<TestimonialCard key={review.username} {...review} />
))}
</Marquee>
{/* Vertical Marquee (upwards) */}
<Marquee vertical pauseOnHover reverse repeat={3} className="[--duration:40s]">
{testimonials.map((review) => (
<TestimonialCard key={review.username} {...review} />
))}
</Marquee>
{/* Gradient overlays for vertical marquee */}
<div className="pointer-events-none absolute inset-x-0 top-0 h-1/4 bg-gradient-to-b from-background"></div>
<div className="pointer-events-none absolute inset-x-0 bottom-0 h-1/4 bg-gradient-to-t from-background"></div>
<div className="pointer-events-none absolute inset-y-0 left-0 w-1/4 bg-gradient-to-r from-background"></div>
<div className="pointer-events-none absolute inset-y-0 right-0 w-1/4 bg-gradient-to-l from-background"></div>
</div>
</div>
);
}
















