Transcription
A composable component for displaying interactive, synchronized transcripts from AI SDK transcribe() results with click-to-seek functionality.
The Transcription component provides a flexible scoped slots interface for displaying audio transcripts with synchronized playback. It automatically highlights the current segment based on playback time and supports click-to-seek functionality for interactive navigation.
Install using CLI
Install Manually
Copy and paste the following code into your project.
Features
- Scoped slots pattern for maximum flexibility
- Automatic segment highlighting based on current time
- Click-to-seek functionality for interactive navigation
- Controlled and uncontrolled component patterns
- Automatic filtering of empty segments
- Visual state indicators (active, past, future)
- Built on Vue's
provide/injectfor flexible state management - Full TypeScript support with AI SDK transcription types
Props
<Transcription />
Root component that provides context and manages transcript state. Uses scoped slots for rendering segments.
<TranscriptionSegment />
Individual segment button with automatic state styling and click-to-seek functionality.
Emits
<Transcription />
Behavior
Scoped Slots Pattern
The component uses a scoped slots pattern where the default slot receives each segment and its index. This provides maximum flexibility for custom rendering while still benefiting from automatic state management and context.
Segment Highlighting
Segments are automatically styled based on their relationship to the current playback time:
- Active (
isActive): WhencurrentTimeis within the segment's time range. Styled with primary color. - Past (
isPast): WhencurrentTimeis after the segment's end time. Styled with muted foreground. - Future: When
currentTimeis before the segment's start time. Styled with dimmed muted foreground.
Click-to-Seek
When a segment is clicked, it calls the internal seek handler which updates the currentTime and emits a seek event with the segment's start time, allowing your audio/video player to seek to that position.
Empty Segment Filtering
The component automatically filters out segments with empty or whitespace-only text to avoid rendering unnecessary elements.
State Management
Uses Vue's provide/inject and useVModel to support both controlled and uncontrolled patterns. When currentTime is provided via v-model, the component operates in controlled mode. Otherwise, it maintains its own internal state.
Data Format
The component expects segments from the AI SDK transcribe() function:
Styling
The component uses data attributes for custom styling:
data-slot="transcription": Root containerdata-slot="transcription-segment": Individual segment buttondata-active: Present on the currently playing segmentdata-index: The segment's index in the array
Default segment appearance:
- Active segment:
text-primary(primary brand color) - Past segments:
text-muted-foreground - Future segments:
text-muted-foreground/60(dimmed) - Interactive segments:
cursor-pointer hover:text-foreground - Non-interactive segments:
cursor-default
Accessibility
- Uses semantic
<button>elements for interactive segments - Full keyboard navigation support
- Proper button semantics for screen readers
data-activeattribute for assistive technology- Hover and focus states for keyboard users
Notes
- Empty or whitespace-only segments are automatically filtered out
- The component uses
flex-wrapfor responsive text flow - Segments maintain inline layout with
gap-1spacing text-smandleading-relaxedprovide comfortable reading- Click events on segments still fire the
@clickhandler if provided - The
seekevent is emitted when segments are clicked