Live captionsPro
Rolling captions for voice: the recognizer's interim words in gray, settled words in ink, a fixed number of lines that roll up by exactly one line as speech wraps, and an overlay style for video.
On this page
ProA trail conditions line after a storm. Captions roll up a line at a time: unsettled words in gray, settled words in ink, and the cut where the caller spoke over the reply.
Installation
Usage
import { LiveCaptions } from "@/components/ui/chatcn/pro/live-captions"
<LiveCaptions segments={voice.segments} lines={2} size="lg" align="center" agentLabel="Trail line" />Takes the same segments as Transcript, so one stream of speech feeds both. Consecutive turns by one speaker flow into a paragraph and a new speaker starts a new line with their name. The box is exactly lines tall: text is anchored to the bottom, older lines fade out at the top edge, and nothing around the captions ever moves while speech arrives.
Examples
Over video
variant="overlay" puts each line on its own dark box that wraps with the text, like broadcast captions, so it reads on any frame.
ProThe overlay style: every line on its own dark box that wraps with the text, readable on any frame.
States
ProWaiting, interim, settled, cut off, paused, unavailable, long unbroken text and every size.
Props
| Prop | Type | Notes |
|---|---|---|
segments | TranscriptSegment[] | Settled text, unsettled interim, interrupted, speaker |
lines | number | Lines kept on screen, 1 to 6. Default 2 |
size | "sm" | "md" | "lg" | "xl" | 13/20, 15/24, 18/28, 24/32. Default md |
variant | "plain" | "overlay" | overlay boxes each line for video. Default plain |
align | "start" | "center" | Default start |
speakers | boolean | Name the speaker at the start of each turn. Default true |
agentLabel, userLabel | string | Default "Assistant" and "You" |
status | "live" | "paused" | "unavailable" | Paused and unavailable keep the text, one step quieter, under a notice |
message | ReactNode | Shown while unavailable. Say how to fix it |
placeholder | ReactNode | Shown before anything is said |
announce | boolean | Read finished agent lines once. Default true; turn it off when a transcript announces them |
label | string | Accessible name. Default "Live captions" |
Keyboard
Captions are read only and take no focus.
Accessibility
- The window is a
role="log"with live updates off, so screen readers never hear a sentence word by word. Each finished agent line is announced once through a polite status, and history present on mount is not read out. - Speaker names carry a hidden colon, so a screen reader reads "Trail line: Partly." rather than running the name into the words.
- Interim words use the lightest readable gray, never a fade. The cut where the caller spoke over the reply is a hairline plus the words "Cut off", never color alone.
- Unavailable is an alert with the fix. Set
langon the root for captions in another language, and RTL followsdir.
Motion
- Text appends with no per word effects. When speech wraps to a new line, the block is shifted back to where it was and eased up by exactly that distance over 200 ms, so lines glide up instead of jumping. A wrap mid roll starts from where the text shows, so it never snaps.
- Old text fades out at the top through a mask, only while the box overflows.
- Under reduced motion the roll is instant.