Skip to content

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-wall

Also 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:

testimonialWall-view.tsx
'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}
    />
  )
}

Reference

Props12 props, 4 types

Props

TestimonialWall props
PropType
themeThemeInput

Default: the theme around it. The showcase passes the chosen preset here.

–
embeddedboolean

A section inside another page: the host lays it out (no page background, section padding or max width).

default false

false
quotesTestimonialWallQuote[]

The quotes, dealt into the columns in order.

default the demo's sixteen

the demo's sixteen
ratingTestimonialWallRating | null

The rating beside the heading; null hides it.

default the demo's 4.8 from 2,314 reviews

the demo's 4.8 from 2,314 reviews
ctaTestimonialWallCta | null

The link under the wall; null hides it.

default "Read all reviews"

"Read all reviews"
autoplayboolean

Let the columns drift.

default true

true
speednumber

How fast the columns drift, in pixels a second.

default 24

24
loadingboolean

Show skeletons in place of the wall, while the quotes load.

default false

false
localestring

The locale the rating is written in. Default: the YoujProvider's.

–
linkComponentElementType

Renders the links (the call to action, a quote's original): pass your router's Link.

default 'a'

'a'
headingLevel1 | 2 | 3

The heading's level.

default 2

2
copyPartial<TestimonialWallCopy>

Any of the block's strings, to rewrite or translate.

–

TestimonialWallQuote

TestimonialWallQuote props
PropType
idRequiredstring–
quoteRequiredstring

What they said, without quotation marks.

–
highlightstring

A phrase of quote, verbatim, set in full ink; the rest reads a step quieter.

–
authorRequired{ name: string /** Their role ("Staff engineer"). */ role: string company?: string /** An image URL; initials stand in without one. */ avatar?: string }–
markReactNode

The company's glyph, drawn in a 24×24 viewBox (the children of an <svg>), filled with the text color.

–
ratingnumber

Stars out of 5, for a quote from a review.

–
sourcestring

Where it was said ("G2", "Email"), in small type at the top.

–
metric{ value: string; label: string }

A figure that leads the card.

–
hrefstring

The original (a review, a post): the author's name links to it.

–

TestimonialWallRating

TestimonialWallRating props
PropType
scoreRequirednumber

The average, out of 5.

–
countRequirednumber

How many reviews it is out of.

–
sourcesTestimonialWallSource[]–

TestimonialWallSource

TestimonialWallSource props
PropType
nameRequiredstring–
scoreRequirednumber–

TestimonialWallCta

TestimonialWallCta props
PropType
labelRequiredstring–
hrefRequiredstring–
onClickMouseEventHandler<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.

eyebrowtitledescriptionwallLabeloutOfreviewssourcesLabelratedpauseplayshowAllshowFeweremptyloading
Built from6 components
Accessibilitylandmarks, 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.