useSpeechRecognition
Reactive wrapper around the Web Speech Recognition API. Provides start/stop/toggle controls with real-time transcript and status tracking.
Speech-to-text via the SpeechRecognition API. Click Start and speak into your microphone.
import { const useSpeechRecognition: (options?: DeepMaybeObservable<UseSpeechRecognitionOptions>) => UseSpeechRecognitionReturn
useSpeechRecognition } from "@usels/web";
function function SpeechToText(): JSX.Element
SpeechToText() { const { const isSupported$: ReadonlyObservable<boolean>
isSupported$, const isListening$: ReadonlyObservable<boolean>
Whether currently listening
isListening$, const result$: ReadonlyObservable<string>
Recognized text
result$, const start: () => void
Start recognition
start, const stop: () => void
Stop recognition
stop } = function useSpeechRecognition(options?: DeepMaybeObservable<UseSpeechRecognitionOptions>): UseSpeechRecognitionReturn
Framework-agnostic reactive wrapper around the
Web Speech Recognition API.
Each start() call instantiates a fresh SpeechRecognition object using the
latest option values, so reactive option updates take effect on the next
start() without needing to recreate the hook. Cleanup is registered via
onUnmount.
useSpeechRecognition();
return ( <JSX.IntrinsicElements.div: DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div> <JSX.IntrinsicElements.p: DetailedHTMLProps<HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p>Supported: {const isSupported$: ReadonlyObservable<boolean>
isSupported$.ImmutableObservableBase<boolean>.get(trackingType?: TrackingType | GetOptions): {}
get() ? "Yes" : "No"}</JSX.IntrinsicElements.p: DetailedHTMLProps<HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p> <JSX.IntrinsicElements.p: DetailedHTMLProps<HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p>Listening: {const isListening$: ReadonlyObservable<boolean>
Whether currently listening
isListening$.ImmutableObservableBase<boolean>.get(trackingType?: TrackingType | GetOptions): {}
get() ? "Yes" : "No"}</JSX.IntrinsicElements.p: DetailedHTMLProps<HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p> <JSX.IntrinsicElements.p: DetailedHTMLProps<HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p>Transcript: {const result$: ReadonlyObservable<string>
Recognized text
result$.ImmutableObservableBase<string>.get(trackingType?: TrackingType | GetOptions): {}
get()}</JSX.IntrinsicElements.p: DetailedHTMLProps<HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p> <JSX.IntrinsicElements.button: DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>
button DOMAttributes<HTMLButtonElement>.onClick?: MouseEventHandler<HTMLButtonElement> | undefined
onClick={() => const start: () => void
Start recognition
start()}>Start</JSX.IntrinsicElements.button: DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>
button> <JSX.IntrinsicElements.button: DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>
button DOMAttributes<HTMLButtonElement>.onClick?: MouseEventHandler<HTMLButtonElement> | undefined
onClick={() => const stop: () => void
Stop recognition
stop()}>Stop</JSX.IntrinsicElements.button: DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>
button> </JSX.IntrinsicElements.div: DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div> );}import { createSpeechRecognition } from "@usels/web";
function SpeechToText() { "use scope"; const { isSupported$, isListening$, result$, start, stop } = createSpeechRecognition();
return ( <div> <p>Supported: {isSupported$.get() ? "Yes" : "No"}</p> <p>Listening: {isListening$.get() ? "Yes" : "No"}</p> <p>Transcript: {result$.get()}</p> <button onClick={() => start()}>Start</button> <button onClick={() => stop()}>Stop</button> </div> );}With options
Section titled “With options”// @noErrorsimport { useSpeechRecognition } from "@usels/web";
function KoreanSpeech() { const { isListening$, isFinal$, result$, toggle } = useSpeechRecognition({ lang: "ko-KR", continuous: true, interimResults: true, });
return ( <div> <p>{isFinal$.get() ? result$.get() : `(interim) ${result$.get()}`}</p> <button onClick={() => toggle()}>{isListening$.get() ? "Stop" : "Start"}</button> </div> );}Reactive options
Section titled “Reactive options”Options accept DeepMaybeObservable. Each field can be a plain value or an Observable. Changes take effect on the next start() call.
// @noErrorsimport { observable } from "@usels/core";import { useSpeechRecognition } from "@usels/web";
function DynamicRecognition() { const lang$ = observable("en-US");
const { isListening$, result$, toggle } = useSpeechRecognition({ lang: lang$, continuous: false, });
return ( <div> <select value={lang$.get()} onChange={(e) => lang$.set(e.target.value)}> <option value="en-US">English</option> <option value="ko-KR">Korean</option> <option value="ja-JP">Japanese</option> </select> <p>Transcript: {result$.get()}</p> <button onClick={() => toggle()}>{isListening$.get() ? "Stop" : "Start"}</button> </div> );}isSupported$ reflects whether the browser supports the Web Speech Recognition API. Always check this before rendering controls.
isFinal$ is true when the current result$ is a finalized transcript. When interimResults is true, interim results are streamed in real-time and isFinal$ is false until the recognition engine commits.
error$ exposes the last SpeechRecognitionError event data, or undefined if no error has occurred.
options is DeepMaybeObservable. Each option field can be a plain value or an Observable. All options are read at each start() call.
Parameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
options | UseSpeechRecognitionOptions (optional) | - |
UseSpeechRecognitionOptions
Section titled “UseSpeechRecognitionOptions”Returns
Section titled “Returns”UseSpeechRecognitionReturn
| Name | Type | Description |
|---|---|---|
isListening$ | ReadonlyObservable<boolean> | Whether currently listening |
isFinal$ | ReadonlyObservable<boolean> | Whether current result is final |
result$ | ReadonlyObservable<string> | Recognized text |
error$ | ReadonlyObservable<SpeechRecognitionErrorEvent | undefined> | Recognition error |
start | () => void | Start recognition |
stop | () => void | Stop recognition |
toggle | (value?: boolean | undefined) => void | Toggle recognition |
isSupported$ | ReadonlyObservable<boolean> | - |