Social proof
Sections that build trust: a wall of what customers say, logos and ratings, a logo cloud, a customer story, headline metrics and a security overview.
Installation & usage
npx @youj/cli add marketing-testimonial-wallAlso installs avatar, button, icon-arrow-right, icon-play, icon-star, marquee, rating, reveal, skeleton, youj-core, youj-presets, youj-ui-core.
The CLI copies the block to blocks/marketing/testimonial-wall.tsx with every component it uses, so it’s yours to edit.
Every prop is optional and falls back to the demo, so it renders as you see it until you pass your own. Give it your data, rewrite or translate its strings through copy, and connect its actions:
'use client'
import Link from 'next/link'
import { TestimonialWall, type TestimonialWallProps } from '@/blocks/marketing/testimonial-wall'
export function TestimonialWallView({ quotes }: Pick<TestimonialWallProps, 'quotes'>) {
return (
<TestimonialWall
quotes={quotes}
copy={{ eyebrow: 'Wall of love' }}
linkComponent={Link}
/>
)
}Description
Let customers make the case in their own words: columns of quotes drift past each other with no seam, the column you point at eases to a stop while the others recede, and one button pauses the whole wall. Each quote sets the phrase that matters in full ink. Under reduced motion the columns stand still, folded, with Show all.
Show who else uses the product in one section: a rating summary, the customers' wordmarks on a hairline grid lit by the pointer with an industry filter, and the featured customer story as an editorial panel whose results roll up. Pointing at a customer with a story says so.
The customers' logos under one quiet line: a grid that trades its logos in place, one cell at a time (the leaving logo drifts up and blurs away as the next rises in), so twice the customers fit in the same room; or, with variant="marquee", a row that drifts with no seam. It rests while pointed at or off screen, and a small button pauses it.
Tell a customer story as a long read: results as counting figures with a before and now bar, chapters with a contents that follows the reader, a pull quote and the next story.
Back claims with numbers that come with context: figures that count up for a chosen period, the change on the one before, a trend line, a baseline and a footnote for the source.
Answer a security review in one place: live status with a strip of daily uptime, certifications with a report on request, data residency on a map, the practices behind it and the policy documents.
Code
Testimonial Wall, the Testimonial wall story: the files youj add writes.
blocks/marketing
Reference
Props12 props, 4 types
Props
| Prop | Type | |
|---|---|---|
theme | ThemeInputDefault: the theme around it. The showcase passes the chosen preset here. | – |
embedded | booleanA section inside another page: the host lays it out (no page background, section padding or max width). default false | false |
quotes | TestimonialWallQuote[]The quotes, dealt into the columns in order. default the demo's sixteen | the demo's sixteen |
rating | TestimonialWallRating | nullThe rating beside the heading; default the demo's 4.8 from 2,314 reviews | the demo's 4.8 from 2,314 reviews |
cta | TestimonialWallCta | nullThe link under the wall; default "Read all reviews" | "Read all reviews" |
autoplay | booleanLet the columns drift. default true | true |
speed | numberHow fast the columns drift, in pixels a second. default 24 | 24 |
loading | booleanShow skeletons in place of the wall, while the quotes load. default false | false |
locale | stringThe locale the rating is written in. Default: the YoujProvider's. | – |
linkComponent | ElementTypeRenders the links (the call to action, a quote's original): pass your router's Link. default 'a' | 'a' |
headingLevel | 1 | 2 | 3The heading's level. default 2 | 2 |
copy | Partial<TestimonialWallCopy>Any of the block's strings, to rewrite or translate. | – |
TestimonialWallQuote
| Prop | Type | |
|---|---|---|
idRequired | string | – |
quoteRequired | stringWhat they said, without quotation marks. | – |
highlight | stringA phrase of | – |
authorRequired | { name: string /** Their role ("Staff engineer"). */ role: string company?: string /** An image URL; initials stand in without one. */ avatar?: string } | – |
mark | ReactNodeThe company's glyph, drawn in a 24×24 viewBox (the children of an | – |
rating | numberStars out of 5, for a quote from a review. | – |
source | stringWhere it was said ("G2", "Email"), in small type at the top. | – |
metric | { value: string; label: string }A figure that leads the card. | – |
href | stringThe original (a review, a post): the author's name links to it. | – |
TestimonialWallRating
| Prop | Type | |
|---|---|---|
scoreRequired | numberThe average, out of 5. | – |
countRequired | numberHow many reviews it is out of. | – |
sources | TestimonialWallSource[] | – |
TestimonialWallSource
| Prop | Type | |
|---|---|---|
nameRequired | string | – |
scoreRequired | number | – |
TestimonialWallCta
| Prop | Type | |
|---|---|---|
labelRequired | string | – |
hrefRequired | string | – |
onClick | MouseEventHandler<HTMLAnchorElement> | – |
Strings14 keys for copy
Strings
copy takes any of these keys; the rest keep their defaults. A key whose text holds a value (a count, a name) takes a function.
eyebrowtitledescriptionwallLabeloutOfreviewssourcesLabelratedpauseplayshowAllshowFeweremptyloadingAccessibilitylandmarks, headings, filters, moving content, live regions
Accessibility
Each section is a <section> named by its own heading (aria-labelledby); the heading is an h2 by default and headingLevel changes it. Customer story is an article with its own header and footer.
Testimonial wall is a named list that screen readers read once: the columns' repeats are inert and hidden from assistive technology. The moving wall has a Pause button (WCAG 2.2.2) and stops a column while it is pointed at or holds focus, bringing a focused link clear of the faded edge; stars are read as "Rated 5 out of 5", and the folded wall's Show all reports aria-expanded.
Logo cloud gives screen readers every customer once, as a named list, and hides the moving picture; its pause button names what it does, and it never moves under reduced motion.
Logos and ratings names its rating group and gives the logo wall a labelled filter whose buttons use aria-pressed; customers with a story are buttons named "read the story", the others images with a label, and the story tabs work from the keyboard. Metrics reads each figure with visually hidden context (the change and period) and announces a period switch in a status region. Customer story gives its results and contents nav labels. Security labels its lists, and the data residency list announces the selected region in a live region.
Figures that count up end on the same text a screen reader gets. The animated parts check the reduced-motion setting. Links and buttons are real a and button elements with the kit’s focus ring.