Skip to content

Instantly share code, notes, and snippets.

@hoseinhamzei
Created November 8, 2025 07:12
Show Gist options
  • Select an option

  • Save hoseinhamzei/a784d81acf5228876d57b1b3cf743aed to your computer and use it in GitHub Desktop.

Select an option

Save hoseinhamzei/a784d81acf5228876d57b1b3cf743aed to your computer and use it in GitHub Desktop.
React useTTS hook for native browser TTS
import React from "react";
import { useSpeech } from "./useSpeech";
export const SpeechDemo = () => {
const { speaking, speak, stop } = useSpeech({ lang: "en-US", rate: 1.1 });
const message = "Accessibility makes your app more inclusive and user-friendly.";
return (
<div>
<p>{message}</p>
<button onClick={() => speak(message)}>
{speaking ? "Stop Reading" : "Read Aloud"}
</button>
<button onClick={stop}>Stop</button>
</div>
);
};
import { useState } from "react";
interface UseSpeechOptions {
lang?: string;
rate?: number;
pitch?: number;
voice?: SpeechSynthesisVoice | null;
}
interface UseSpeechReturn {
speaking: boolean;
speak: (text: string) => void;
stop: () => void;
}
export const useSpeech = (options: UseSpeechOptions = {}): UseSpeechReturn => {
const { lang = "en-US", rate = 1, pitch = 1, voice = null } = options;
const [speaking, setSpeaking] = useState(false);
const stop = () => {
window.speechSynthesis.cancel();
setSpeaking(false);
};
const speak = (text: string) => {
if (!("speechSynthesis" in window)) {
alert("Sorry, your browser does not support text-to-speech.");
return;
}
if (speaking) {
stop();
return;
}
const utterance = new SpeechSynthesisUtterance(text);
utterance.lang = lang;
utterance.rate = rate;
utterance.pitch = pitch;
utterance.voice = voice || window.speechSynthesis.getVoices()[0] || null;
utterance.onend = () => setSpeaking(false);
window.speechSynthesis.speak(utterance);
setSpeaking(true);
};
return { speaking, speak, stop };
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment