All hooks / Browser APIs

useSpeechSynthesis

631 B minified and brotliedSourceMarkdown✓ Works in all modern browsers

Reads text aloud with the browser's speech synthesis, with the voice list and whether it is speaking.

Handles the browser quirks: voices load after the page (the list is empty at first and fills in with a re-render), Chrome stops long text after about 15 seconds (text is read in sentence-sized parts), and Chrome can garbage collect an utterance mid-sentence so its end never fires (they are kept until done). Stops on unmount.

Import

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

Usage

const { supported, speaking, speak, cancel } = useSpeechSynthesis()
if (!supported) return null
return speaking
  ? <button onClick={cancel}>Stop</button>
  : <button onClick={() => speak(answer, { rate: 1.1 })}>Read aloud</button>

Live demo

Reads the sentence below aloud.

React tils renders the right first frame. Hooks read browser state without hydration mismatches, and clean up after themselves.

not supported

When to use it

A "Read aloud" button for AI answers, articles, or lessons, or spoken feedback in a hands-free flow.

When not to

You need natural, consistent voices across devices; generate audio with a text-to-speech API and play it. Voices differ by browser and operating system.

API

function useSpeechSynthesis(): SpeechSynthesisState

Returns { supported, voices, speaking, speak, cancel }.

Types

export type SpeakOptions = {
  /** One of `voices`. Default: the browser's default voice for `lang`. */
  voice?: SpeechSynthesisVoice | null;
  /** BCP 47 language, e.g. `'en-US'`. Default: the page's language. */
  lang?: string;
  /** 0.1 to 10. Default `1`. */
  rate?: number;
  /** 0 to 2. Default `1`. */
  pitch?: number;
  /** 0 to 1. Default `1`. */
  volume?: number;
};
export type SpeechSynthesisState = {
  /** `false` on the server, during hydration, and in browsers without speech synthesis. */
  supported: boolean;
  /** Installed voices. Empty on the server and until the browser has loaded them. */
  voices: SpeechSynthesisVoice[];
  speaking: boolean;
  /** Read `text` aloud. The browser has one speech queue, so this stops anything the page was reading. */
  speak: (text: string, options?: SpeakOptions) => void;
  /** Stop reading. */
  cancel: () => void;
};

Browser support

UsesChromeEdgeFirefoxSafariChrome AndroidSafari iOS
Speech synthesisWidely available33+14+49+7+33+7+
  • Where the API is missing, supported is false. The voices on offer depend on the browser and operating system.

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 useSpeech, useTextToSpeech, react-speech-kit.