Skip to main content
WireKit
Copy for LLM

Testimonial

A testimonial is a quotation with an attribution, and that is exactly what <x-wirekit::testimonial> renders: a <figure> wrapping a <blockquote> and a <figcaption>. A screen reader announces it as a quote and reads the attribution as belonging to it — which a stack of styled <div>s never does, however much it looks the part.

Three testimonials with ratings
  • We replaced four hand-built components with one and the accessibility review came back clean on the first pass.
    Ada Lovelace Ada Lovelace Principal Engineer, Analytical
  • The parts I usually have to fight — focus order, keyboard traps, dark mode — were simply already right.
    Grace Hopper Grace Hopper CTO, Compiler Works
  • Every component takes tokens, so our whole brand landed by editing one file. No forks, no overrides.
    Alan Turing Alan Turing Head of Platform, Enigma

Attribution

author is what makes a testimonial a testimonial. role adds the context that makes it persuasive.

Without an avatar, the component derives the author's initials and renders them in a deterministic color rather than showing an empty gray disc — the same person always gets the same color. Pass initials yourself for a mononym, a brand account, or any name where first-and-last-letter is the wrong reading.

{{-- Photo --}}
<x-wirekit::testimonial author="Ada Lovelace" role="Principal Engineer" avatar="/img/ada.jpg">
    …
</x-wirekit::testimonial>

{{-- No photo — initials are derived ("AL") --}}
<x-wirekit::testimonial author="Ada Lovelace" role="Principal Engineer">
    …
</x-wirekit::testimonial>

{{-- Override the derived initials --}}
<x-wirekit::testimonial author="Björk" initials="B">
    …
</x-wirekit::testimonial>

Rating

rating renders a read-only star rating above the quote. It is a record of what someone gave, never an input — the stars are not focusable and cannot be changed.

<x-wirekit::testimonial author="Grace Hopper" :rating="5">
    …
</x-wirekit::testimonial>

logo places a company mark at the end of the attribution.

Leave logo-alt unset when the author is already named in text: the logo is then decoration, and giving it a name only makes a screen reader read the company twice. Pass logo-alt when the logo is the only attribution.

{{-- Author named in text -> the logo is decorative and stays silent --}}
<x-wirekit::testimonial author="Alan Turing" role="Head of Platform, Enigma" logo="/img/enigma.svg">
    …
</x-wirekit::testimonial>

{{-- Logo carries the attribution on its own -> name it --}}
<x-wirekit::testimonial author="" logo="/img/enigma.svg" logo-alt="Enigma">
    …
</x-wirekit::testimonial>

The grid

<x-wirekit::testimonial-grid> is a labeled list — a real <ul> whose children are <li> elements. That is not decoration: it means a screen reader announces "list, 3 items" before the quotes, so someone who cannot see the row knows how many there are to get through.

It flows one column on a phone, two on a tablet, three on a desktop, and stretches every quote to the height of the tallest so the row keeps a clean baseline however uneven the copy is.

<x-wirekit::testimonial-grid label="What developers say">
    <li>
        <x-wirekit::testimonial author="Ada Lovelace">…</x-wirekit::testimonial>
    </li>
    <li>
        <x-wirekit::testimonial author="Grace Hopper">…</x-wirekit::testimonial>
    </li>
</x-wirekit::testimonial-grid>

Props

<x-wirekit::testimonial>

Prop Type Default Description
author string '' Who said it.
role string|null null Their role / company.
avatar string|null null Author photo URL. Omit to render derived initials.
initials string|null null Override the derived initials.
logo string|null null Company logo URL.
logoAlt string|null null Accessible name for the logo. Omit when the author is named in text.
rating int|float|null null Read-only star rating (0–5).
scope string|null null Class-scope override.

<x-wirekit::testimonial-grid>

Prop Type Default Description
label string 'Testimonials' Accessible name for the list of quotes.
scope string|null null Class-scope override.

Accessibility

  • The quote is a real <blockquote> inside a <figure>, attributed by a <figcaption> — announced as a quotation with its source, not as loose text.
  • The grid is a labeled <ul role="list"> of <li> items, so the number of quotes is announced up front.
  • The star rating is read-only and not focusable — it is a record, not a control.
  • A decorative company logo renders alt="" and is skipped, so the company is not announced twice when the author already names it.
  • Initials are derived with multibyte-safe string handling, so a non-ASCII name is never sliced mid-codepoint.

Keyboard Interaction

None. A testimonial is content, not a control — there is nothing here to operate. The read-only star rating is deliberately not focusable, so tabbing through a wall of quotes never traps a keyboard user in decorative stars. Any link you place inside the quote keeps its own normal tab behavior.