Sora UI
Voice

Transcript Viewer

A component for displaying an audio transcript with word-by-word highlighting synced to audio playback.

Loading transcript...

Installation

Option A: Via Sora UI CLI (Recommended)

If your project uses `shadcn/ui`, you can install this component and its dependencies automatically:

npx soraui-cli add transcript-viewer

Option B: Manual Copy-Paste

1. Copy the code from the Code > Component tab above.
2. Paste it in your project at components/transcript-viewer.tsx.
3. Install the dependencies:
npm install clsx tailwind-merge lucide-react

API Reference

Transcript Viewer is built as a flexible set of compound components, giving you full control over layout, audio binding, word styling, and controls.

TranscriptViewerContainer Props

PropTypeDefaultDescription
audioSrcstringOptional URL to an audio file. If omitted, uses Web Speech API or simulated timeline.
alignmentCharacterAlignmentResponseModelMOCK_ALIGNMENTOptional custom alignment model containing character timings.
componentColorstring"var(--card)"Container card background color.

TranscriptViewerWords Props

PropTypeDefaultDescription
highlightBgstring"var(--primary)"Background highlight color for the currently spoken word.
highlightTextstring"var(--primary-foreground)"Text color for the currently active word.
wordClassNamesstringAdditional CSS classes applied to individual word spans.
gapClassNamesstringAdditional CSS classes applied to word gaps.
renderWord(props: { word, status }) => ReactNodeCustom render function for word elements.

TranscriptViewerScrubBar Props

PropTypeDefaultDescription
showTimeLabelsbooleantrueWhether to render current time and duration labels.
trackClassNamestringCustom classes for the track background bar.
progressClassNamestringCustom classes for the active progress fill.
thumbClassNamestringCustom classes for the draggable scrubber thumb.

Examples

Compound Component Pattern

Standard setup composing container, words, play/pause trigger, and progress scrub bar.

App.tsx
import {
  TranscriptViewerContainer,
  TranscriptViewerAudio,
  TranscriptViewerWords,
  TranscriptViewerPlayPauseButton,
  TranscriptViewerScrubBar
} from "@/components/transcript-viewer";

export default function Demo() {
  return (
    <TranscriptViewerContainer>
      <TranscriptViewerAudio />
      <TranscriptViewerWords 
        highlightBg="#ffffff"
        highlightText="#09090b"
      />
      <div className="flex items-center gap-4 w-full">
        <TranscriptViewerPlayPauseButton />
        <TranscriptViewerScrubBar className="flex-1" />
      </div>
    </TranscriptViewerContainer>
  );
}

Custom Character Alignment

Pass timestamps matching ElevenLabs or custom speech-to-text API alignment models.

App.tsx
import {
  TranscriptViewerContainer,
  TranscriptViewerAudio,
  TranscriptViewerWords,
  TranscriptViewerPlayPauseButton,
  TranscriptViewerScrubBar
} from "@/components/transcript-viewer";

const myAlignment = {
  characters: ["H", "e", "l", "l", "o", " ", "w", "o", "r", "l", "d"],
  character_start_times_seconds: [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0],
  character_end_times_seconds: [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.2],
};

export default function CustomAlignmentDemo() {
  return (
    <TranscriptViewerContainer 
      alignment={myAlignment}
      audioSrc="/sample/audio.mp3"
    >
      <TranscriptViewerAudio />
      <TranscriptViewerWords />
      <div className="flex items-center gap-4 w-full">
        <TranscriptViewerPlayPauseButton />
        <TranscriptViewerScrubBar className="flex-1" />
      </div>
    </TranscriptViewerContainer>
  );
}