Skip to content
Sensors

useSpeechRecognition

Reactive wrapper around the Web Speech Recognition API. Provides start/stop/toggle controls with real-time transcript and status tracking.

Speech Recognition
Not Supported

Speech-to-text via the SpeechRecognition API. Click Start and speak into your microphone.

SpeechRecognition is not supported in this browser.
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
>
);
}
// @noErrors
import { 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>
);
}

Options accept DeepMaybeObservable. Each field can be a plain value or an Observable. Changes take effect on the next start() call.

// @noErrors
import { 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.

ParameterTypeDescription
optionsUseSpeechRecognitionOptions (optional)-
OptionTypeDefaultDescription
langstring-Language for recognition. Default: “en-US”
continuousboolean-Continuous recognition. Default: true
interimResultsboolean-Return interim results. Default: true
maxAlternativesnumber-Maximum number of alternatives per result. Default: 1
windowWindowSource--

UseSpeechRecognitionReturn

NameTypeDescription
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() => voidStart recognition
stop() => voidStop recognition
toggle(value?: boolean | undefined) => voidToggle recognition
isSupported$ReadonlyObservable<boolean>-

View on GitHub