Testimonials
Customers in their own words.
- 5 blocks
- 2 free
- 3 Pro
- Light and dark
- Responsive
Unlock 55 Pro blocks and every template
Every preview is open. With Pro you get the code, copy-paste ready, with every update for good.
Testimonial wall
FreeQuotes with ratings and faces, in columns.
testimonials-grid.tsx
"use client";
import { Avatar, Rating } from "@waveinno/ui";
const QUOTES = [
{ name: "Karim Ahmed", role: "Owner, Gulshan Parking", rating: 5, text: "We used to count cash at midnight and still be short. Now the day closes itself, to the taka, before I leave the office." },
{ name: "Nusrat Jahan", role: "Operations, Jamuna Future Park", rating: 5, text: "Weekend queues at the exit went from twenty minutes to two. The plate camera just opens the gate." },
{ name: "Rafiq Islam", role: "Site manager, Banani", rating: 4.5, text: "My attendants learned it in an afternoon, in Bangla. That alone sold it." },
{ name: "Farhana Akter", role: "CFO, Unimart", rating: 5, text: "Reports that match the bank statement. I did not think that was possible for parking." },
{ name: "Tanvir Hasan", role: "IT lead, Square Hospital", rating: 5, text: "Their gate controllers kept working through a two-hour internet outage and synced the moment it came back." },
{ name: "Sadia Islam", role: "Owner, Mirpur 10 lot", rating: 5, text: "I run a small lot. Free plan, bKash, done. I upgraded when I opened the second one." },
];
export default function TestimonialsGrid() {
return (
<section className="mx-auto max-w-6xl px-4 py-20 sm:px-6">
<div className="mx-auto max-w-2xl text-center">
<h2 className="disp text-[34px] font-bold tracking-[-0.03em] text-text sm:text-[42px] leading-[1.15]">Owners say it better</h2>
<div className="mt-4 flex items-center justify-center gap-2 text-[14px] text-muted">
<Rating readOnly value={4.9} allowHalf size="sm" /> 4.9 from 230 reviews
</div>
</div>
<div className="mt-12 columns-1 gap-4 sm:columns-2 lg:columns-3">
{QUOTES.map((q, i) => (
<figure
key={q.name}
className={
"mb-4 break-inside-avoid rounded-[20px] border p-6 transition-[transform,box-shadow] duration-300 hover:-translate-y-1 hover:shadow-[var(--lit),0_18px_40px_-22px_rgba(5,8,22,.35)] " +
(i === 1 ? "border-transparent bg-[linear-gradient(150deg,var(--brand-1),var(--brand-2))] text-white [--muted:rgba(255,255,255,.75)] [--text:#fff]" : "border-border bg-raised shadow-[var(--lit)]")
}
>
<Rating readOnly value={q.rating} allowHalf size="sm" />
<blockquote className="mt-4 text-[15px] leading-[1.65] text-text">“{q.text}”</blockquote>
<figcaption className="mt-5 flex items-center gap-3">
<Avatar name={q.name} size="lg" />
<span>
<span className="block text-[13.5px] font-semibold text-text">{q.name}</span>
<span className="block text-[12.5px] text-muted">{q.role}</span>
</span>
</figcaption>
</figure>
))}
</div>
</section>
);
}Simple quote
FreeOne quote, centred, with the person behind it.
testimonial-simple.tsx
import { Avatar, Rating } from "@waveinno/ui";
export default function TestimonialSimple() {
return (
<section className="px-4 py-24 sm:px-6">
<figure className="mx-auto max-w-3xl text-center">
<Rating readOnly value={5} className="justify-center" />
<blockquote className="disp mt-7 text-[24px] font-semibold leading-[1.45] tracking-[-0.02em] text-text sm:text-[30px]">
“We used to count cash at midnight and still be short. Now the day closes itself, to the taka, before I leave the office.”
</blockquote>
<figcaption className="mt-9 flex items-center justify-center gap-3.5">
<Avatar name="Karim Ahmed" size="lg" />
<span className="text-left">
<span className="block text-[15px] font-semibold text-text">Karim Ahmed</span>
<span className="block text-[13.5px] text-muted">Owner, Gulshan Parking · 3 sites</span>
</span>
</figcaption>
</figure>
</section>
);
}One big quote with the numbers behind it.
Two rows of quotes drifting in opposite directions.
Quotes that change on their own; faces as the controls.