Trusted by teams shipping faster
Use app-owned testimonial data to add focused social proof to a landing page, pricing page, or launch announcement.
Stackhacker UI gave our team a polished starting point without locking us into a product model. We shipped our customer portal redesign in half the time.
The blocks feel production-ready, but still simple enough for our engineers to understand and adapt. That balance is hard to find.
We could bring our own data, avatars, and copy while keeping the interface consistent with our design system. It removed a lot of busywork.
Installation
pnpm dlx shadcn-vue@latest add "https://ui.stackhacker.io/r/testimonials.json"
Usage
<script setup lang="ts">
import { Testimonials, type TestimonialItem } from "@/components/testimonials";
const testimonials: TestimonialItem[] = [
{
id: "sarah-chen",
quote: "The redesign reduced support tickets and made onboarding feel effortless.",
author: {
name: "Sarah Chen",
role: "Product Director, Bloom Finance",
avatar: {
src: "/avatars/sarah.jpg",
alt: "Sarah Chen",
},
},
},
];
</script>
<template>
<Testimonials :items="testimonials" />
</template>App-Owned Testimonials
Testimonials owns the section layout, quote cards, accessible author rendering, and simple avatar fallback. Your app owns testimonial collection, moderation, ordering, source mapping, avatar storage, image optimization, carousel behavior, analytics, and any CMS or API integration.
Pass already-approved, display-ready testimonial items to the component. Keep remote fetching, caching, personalization, and rotation logic in app code so the registry item remains portable.
Examples
Default
Trusted by teams shipping faster
Use app-owned testimonial data to add focused social proof to a landing page, pricing page, or launch announcement.
Stackhacker UI gave our team a polished starting point without locking us into a product model. We shipped our customer portal redesign in half the time.
The blocks feel production-ready, but still simple enough for our engineers to understand and adapt. That balance is hard to find.
We could bring our own data, avatars, and copy while keeping the interface consistent with our design system. It removed a lot of busywork.
Without Avatars
Avatar fallbacks
Testimonials stay readable when app-owned avatar data is missing or fails to load.
The fallback initials keep author identity clear even when a profile photo is not available.
A failed avatar image falls back to initials without changing the testimonial layout.
<Testimonials
:items="[
{
id: 'no-avatar',
quote: 'The component still renders author identity clearly without an image.',
author: { name: 'Jordan Lee', role: 'Founder, Northstar Labs' },
},
]"
/>API Reference
Props
| Prop | Type | Default | Description |
|---|---|---|---|
title | string | "What our customers say" | Section heading shown above the testimonials. |
description | string | "Real feedback from teams using this product to move faster." | Optional supporting copy shown below the title. |
items | TestimonialItem[] | [] | Testimonials supplied by your app. |
class | HTMLAttributes["class"] | — | Additional CSS classes for the section. |
Item Type
| Field | Type | Description |
|---|---|---|
id | string | Stable item id. Falls back to author name plus index when omitted. |
quote | string | Testimonial quote text. |
author | TestimonialAuthor | Person or organization credited for the quote. |
Author Type
| Field | Type | Description |
|---|---|---|
name | string | Author display name. |
role | string | Optional role, company, or byline. |
description | string | Optional legacy-friendly byline. Used when role is omitted. |
avatar | TestimonialAvatar | Optional avatar image supplied by your app. |
Avatar Type
| Field | Type | Description |
|---|---|---|
src | string | Avatar image source. |
alt | string | Optional alt text. Falls back to author name. |
srcset | string | Optional responsive source set. |

