All hooks / Browser APIs

useSpeechRecognition

514 B minified and brotliedSourceMarkdown! Not available in Firefox

Turns speech from the microphone into text with the browser's built-in speech recognition: the final transcript, the words still being recognized, and whether it is listening.

Works in Chrome, Edge, and Safari; supported is false in Firefox. Chrome sends the audio to Google's servers to recognize it, so it needs a connection. Recognition stops by itself after a pause unless continuous is set, and always on unmount.

Import

import { useSpeechRecognition } from '@vincent.ri/react-tils'
// or only this hook
import { useSpeechRecognition } from '@vincent.ri/react-tils/useSpeechRecognition'

Usage

const speech = useSpeechRecognition({ lang: 'en-US' })
useEffect(() => {
  if (speech.transcript) setQuery(speech.transcript)
}, [speech.transcript])
if (!speech.supported) return null
return (
  <button onClick={speech.listening ? speech.stop : speech.start}>
    {speech.listening ? 'Stop' : '🎤 Dictate'}
  </button>
)

Live demo

Click and speak. Chrome, Edge, and Safari.

not supported

When to use it

Dictation into a search box, chat input, or note, as an optional extra next to typing.

When not to

You need it in every browser, offline, or with consistent accuracy; record audio with useMediaRecorder and send it to a transcription API. Don't make it the only way to enter text.

API

function useSpeechRecognition(options?: SpeechRecognitionOptions): SpeechRecognitionState
ParameterDescription
optionslang, continuous. Optional.

Returns { supported, listening, transcript, interim, error, start, stop, reset }.

Types

export type SpeechRecognitionOptions = {
  /** BCP 47 language, e.g. `'en-US'`. Default: the page's language. */
  lang?: string;
  /** Keep listening across pauses instead of stopping after the first phrase. Default `false`. */
  continuous?: boolean;
};
export type SpeechRecognitionState = {
  /** `false` on the server, during hydration, and in browsers without speech recognition (Firefox). */
  supported: boolean;
  listening: boolean;
  /** Everything recognized so far, final words only. */
  transcript: string;
  /** Words still being recognized; they may change before becoming final. */
  interim: string;
  /** e.g. `'not-allowed'` (microphone blocked), `'no-speech'`, `'network'`. */
  error: string | null;
  /** Start listening. Call it from a click: browsers ask for the microphone. */
  start: () => void;
  /** Stop and keep the words heard so far. */
  stop: () => void;
  /** Clear the transcript. */
  reset: () => void;
};

Browser support

UsesChromeEdgeFirefoxSafariChrome AndroidSafari iOS
Speech recognitionLimited availability33+79+✕14.1+33+14.5+
  • Uses SpeechRecognition or its webkit prefixed version. Where neither exists (Firefox), supported is false and start does nothing.

First version with support, from MDN's compatibility data (web-features 3.42.0, @mdn/browser-compat-data 8.1.5).

Coming from another library?

Other libraries call this useSpeechToText, react-speech-recognition, useVoice.