Skip to content
Template Empire
Browse components

Audio Customer Stories

A free audio testimonial section with native playback, selectable customer voices and complete transcripts.

Recorded stories

Choose a voice

03 stories

Selected voice

Nadia Chen, Creative Director at Northline

0:19

“The page finally sounds like the product feels: calm, deliberate and human.”

Nadia Chen, Creative Director at Northline
Ready to play0:19
Read full transcript

We had strong customer quotes, but they were disappearing into a grid that looked like every other landing page. Giving each person a voice changed the pace completely. Visitors can stop, listen and hear the confidence behind the words. The page finally sounds like the product feels: calm, deliberate and human.

Customise

24
0.42
0.35s
24px

Code

<AudioCustomerStories
  stories={stories}
/>

Audio Customer Stories is a free audio testimonial React section for Next.js and React, styled with Tailwind and enhanced with Motion. It presents two to six customer voices as an accessible selector beside a native audio player, a pull quote, a human-readable duration and the complete transcript.

Selecting another story pauses and resets the previous recording without moving focus or starting the new source. The decorative waveform uses deterministic CSS bars and only pulses while native audio is playing on screen, while reduced motion keeps it fully static. Hidden tabs pause playback without resuming it automatically, and every story remains usable through native controls and a standard disclosure.

Install

Add the @te registry to your components.json once:

{
  "registries": {
    "@te": "https://templateempire.io/r/{name}.json"
  }
}

Then install the component:

npx shadcn@latest add @te/quote-audio-stories

Usage

import { AudioCustomerStories } from "@/components/quote-audio-stories";

const stories = [
  {
    id: "nadia-chen",
    audioSrc: "/audio/nadia-chen.mp3",
    quote: "The page finally sounds like the product feels.",
    attribution: "Nadia Chen, Creative Director at Northline",
    duration: "0:42",
    transcript: "The complete transcript of Nadia's customer story.",
  },
  {
    id: "elias-morgan",
    audioSrc: "/audio/elias-morgan.mp3",
    quote: "The native player kept the experience familiar.",
    attribution: "Elias Morgan, Founder at Sunday Press",
    duration: "0:36",
    transcript: "The complete transcript of Elias's customer story.",
  },
];

export function Example() {
  return <AudioCustomerStories stories={stories} />;
}

Props

PropTypeDefaultDescription
storiesReadonlyArray<{ id; audioSrc; quote; attribution; duration; transcript }>requiredTwo to six stories with unique ids, native audio sources, quotations, attributions, display durations and complete transcripts.
initialIdstringundefinedInitially selected story id. An invalid id falls back safely to the first story.
layout"rail" | "split""split"Wide-screen composition. Split places the selector beside the player, while rail places the selector above it.
barCountnumber24Decorative waveform bar count, clamped to 8 to 48.
pulseAmountnumber0.42Maximum scale increase for each active waveform bar, clamped to 0 to 0.8.
crossfadeDurationnumber0.35Quote and player transition duration in seconds, clamped to 0 to 0.8.
radiusnumber24Selector and player corner radius in CSS pixels, clamped to 0 to 44.
onStoryChange(id: string) => voidundefinedCalled after a user changes the selected story.
classNamestringundefinedAdditional classes merged onto the section.

Customisation

Audio Customer Stories exposes four Tier 3 tokens. --audio-stories-accent defaults to var(--primary) for the selected story and active bars, --audio-stories-accent-text defaults to var(--primary-accent) for the transcript summary on hover and focus, --audio-stories-panel defaults to var(--card) for player surfaces, and --audio-stories-wave defaults to var(--muted-foreground) for resting bars. The component also falls back to the library surface and muted tokens when those shadcn tokens are not present. Use the scalar props to tune layout, waveform geometry, transition pace and corner radius:

.audio-stories-theme {
  --audio-stories-accent: var(--ring);
  --audio-stories-accent-text: var(--primary-accent);
  --audio-stories-panel: var(--surface);
  --audio-stories-wave: var(--muted);
}

<AudioCustomerStories
  stories={stories}
  layout="rail"
  barCount={36}
  pulseAmount={0.28}
  crossfadeDuration={0.2}
  radius={16}
  className="audio-stories-theme"
/>

Frequently asked questions

Is Audio Customer Stories free for commercial use?
Yes. Audio Customer Stories is MIT licensed, so you can use it in personal and commercial projects without attribution.
Is this audio testimonial section accessible and performant?
Yes. Story choices are native buttons in a labelled list, the active choice uses aria-current, playback uses native audio controls, quotations use blockquote and cite, and each complete transcript opens through a standard details disclosure. The decorative waveform is hidden from assistive technology and uses fixed CSS transform animation with no audio analysis, timer or per-frame React state. Reduced motion removes waveform animation and the story crossfade while leaving selection, playback and transcripts available. Without JavaScript, every story remains listed with its own native player and transcript.
How can I customise the waveform and player?
Use barCount and pulseAmount to set waveform density and movement, crossfadeDuration to set the story swap pace, radius to shape the cards, and layout to choose a split or rail composition. The playground exposes exactly those effect controls. Retint the selected state, panel and idle bars with the three audio story CSS variables without changing the component source.

Related components

Want the full page this belongs to?Template Empire builds complete Next.js templates with credible social proof sections and the same motion system throughout.Explore Template Empire templates