A composable component for displaying interactive, synchronized transcripts from AI SDK transcribe() results with click-to-seek functionality.
The Transcription component provides a flexible render props 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.
See scripts/transcription.tsx for this example.
npx ai-elements@latest add transcription
useControllableState for flexible state managementRoot component that provides context and manages transcript state. Uses render props pattern for rendering segments.
| Prop | Type | Default | Description |
|---|---|---|---|
segments | TranscriptionSegment[] | - | Array of transcription segments from AI SDK transcribe() function. |
currentTime | number | 0 | Current playback time in seconds (controlled). |
onSeek | (time: number) => void | - | Callback fired when a segment is clicked or when currentTime changes. |
children | (segment: TranscriptionSegment, index: number) => ReactNode | - | Render function that receives each segment and its index. |
...props | Omit<React.ComponentProps< | - | Any other props are spread to the root div element. |
Individual segment button with automatic state styling and click-to-seek functionality.
| Prop | Type | Default | Description |
|---|---|---|---|
segment | TranscriptionSegment | - | The transcription segment data. |
index | number | - | The segment index. |
...props | React.ComponentProps< | - | Any other props are spread to the button element. |
The component uses a render props pattern where the children prop is a
function that receives each segment and its index. This provides maximum
flexibility for custom rendering while still benefiting from automatic state
management and context.
Segments are automatically styled based on their relationship to the current playback time:
isActive): When currentTime is within the segment's time
range. Styled with primary color.isPast): When currentTime is after the segment's end time.
Styled with muted foreground.currentTime is before the segment's start time. Styled with
dimmed muted foreground.When onSeek is provided, segments become interactive buttons. Clicking a
segment calls onSeek with the segment's start time, allowing your audio/video
player to seek to that position.
The component automatically filters out segments with empty or whitespace-only text to avoid rendering unnecessary elements.
Uses Radix UI's useControllableState hook to support both controlled and
uncontrolled patterns. When currentTime is provided, the component operates in
controlled mode. Otherwise, it maintains its own internal state.
The component expects segments from the AI SDK transcribe() function:
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 arrayDefault segment appearance:
text-primary (primary brand color)text-muted-foregroundtext-muted-foreground/60 (dimmed)cursor-pointer hover:text-foregroundcursor-default<button> elements for interactive segmentsdata-active attribute for assistive technologyflex-wrap for responsive text flowgap-1 spacingtext-sm and leading-relaxed provide comfortable readingonClick handler if providedonSeek callback is called both when segments are clicked and when
controlled currentTime changes