Events
Event System
Section titled “Event System”ResponsiveVoice gives you two ways to observe speech:
- Per-call callbacks — passed inline to
speak(), bound to that one utterance, and reset on the nextspeak(). - Global events — registered once with
addEventListener(), firing across everyspeak()call.
Per-call callbacks
Section titled “Per-call callbacks”Pass these in the options object of speak(text, voice?, options?). They belong to a single utterance.
| Callback | Signature | Fires |
|---|---|---|
onstart | () => void | speech begins |
onend | () => void | speech completes |
onerror | (error: Error) => void | an error occurs |
onboundary | (charIndex: number, name: string) => void | crosses a word/sentence boundary (native only) |
rv.speak('Hello world', 'UK English Female', { onstart: () => console.log('Started speaking'), onend: () => console.log('Finished speaking'), onerror: (error) => console.error('Error:', error.message), onboundary: (charIndex, name) => { console.log(`Boundary (${name}) at character ${charIndex}`); },});Global events
Section titled “Global events”Register once with addEventListener(name, handler); they fire across every speak() call. Event names are PascalCase:
| Event | Payload | Fires |
|---|---|---|
OnReady | — | client initialized and ready |
OnLoad | — | alias of OnReady (legacy) |
OnStart | — | an utterance starts |
OnEnd | — | an utterance ends |
OnPause | — | speech is paused |
OnResume | — | speech resumes |
OnError | { error, message? } | an error occurs |
OnVoiceResolved | voice-resolution details | a voice is resolved for an utterance |
OnServiceSwitched | { from, to } | engine switches between native and fallback |
OnPartStart | { partIndex, totalParts, text } | a text chunk starts speaking |
OnPartEnd | { partIndex, totalParts, text } | a text chunk finishes |
OnClickEvent | — | a user gesture (click) is detected |
OnAllowSpeechClicked | { allowed } | user responds to the permission prompt |
rv.addEventListener('OnStart', () => console.log('Speech started'));rv.addEventListener('OnPause', () => console.log('Speech paused'));rv.addEventListener('OnResume', () => console.log('Speech resumed'));Pause and resume are only global events — they are not per-call callbacks. See the RVEventType reference for the complete list of event names.
Removing listeners
Section titled “Removing listeners”Pass the same handler reference you registered:
const handler = () => console.log('Speech started');
rv.addEventListener('OnStart', handler);rv.removeEventListener('OnStart', handler);Error handling
Section titled “Error handling”The per-call onerror callback receives a standard Error. The OnError event delivers a payload { error, message? } whose error is that same Error:
rv.speak('Hello', 'UK English Female', { onerror: (error) => { console.error('Speech failed:', error.message); },});Async/await pattern
Section titled “Async/await pattern”Wrap speak() in a Promise using onend and onerror:
function speakAsync(text: string, voice: string): Promise<void> { return new Promise((resolve, reject) => { rv.speak(text, voice, { onend: () => resolve(), onerror: (error) => reject(error), }); });}
// Usageasync function readParagraphs(paragraphs: string[]) { for (const paragraph of paragraphs) { await speakAsync(paragraph, 'UK English Female'); } console.log('All paragraphs read');}Progress tracking UI
Section titled “Progress tracking UI”Use onboundary to update a progress bar as speech advances (native voices only):
let startTime: number;
rv.speak(longText, 'UK English Female', { onstart: () => { startTime = Date.now(); progressBar.style.width = '0%'; }, onboundary: (charIndex) => { const progress = (charIndex / longText.length) * 100; progressBar.style.width = `${progress}%`; }, onend: () => { progressBar.style.width = '100%'; console.log(`Completed in ${Date.now() - startTime}ms`); },});Queue events
Section titled “Queue events”Each speak() call carries its own callbacks:
rv.speak('First sentence', 'UK English Female', { onend: () => console.log('First done, starting second'),});
rv.speak('Second sentence', 'UK English Female', { onstart: () => console.log('Second starting'), onend: () => console.log('Queue complete'),});