Skip to main content

Speech Component

Basic Usage

import React from "react";
import Speech from "react-text-to-speech";

export default function App() {
return <Speech text="This library is awesome!" />;
}

Highlight Text

Like useSpeech hook, the <Speech> component can also be used to highlight text. Refer Here

With <Speech> component, <HighlightedText> component exported by react-text-to-speech can be used to display the highlighted text.

NOTE: id of both <Speech> and <HighlightedText> should be same to link them together. Additionally, text should be included as children within the <HighlightedText> component as demonstrated below. This helps prevent initial layout shift issues that may arise while react-text-to-speech links both components based on their respective id. It's important to note that the children added in this manner are temporary and will be replaced once the components are successfully linked.

import React, { useMemo } from "react";
import Speech, { HighlightedText } from "react-text-to-speech";

export default function App() {
const text = useMemo(
() => (
<div>
<span>This library is awesome!</span>
<div>
<div>
<span>It can also read and highlight </span>
<span>nested text... </span>
<span>
<span>upto </span>
<span>
any
<span> level.</span>
</span>
</span>
</div>
</div>
</div>
),
[],
);

return (
<>
<Speech id="unique-id" text={text} highlightText={true} />
<HighlightedText id="unique-id">{text}</HighlightedText>
</>
);
}

Multiple Instance Usage

Like useSpeech hook, the <Speech> component can also be used to handle multiple speech instances. Refer Here

import React, { useMemo } from "react";
import Speech from "react-text-to-speech";

function NewsItem({ title, desc }) {
const text = useMemo(
() => (
<>
<h4 style={{ margin: 0 }}>{title}</h4>
<div style={{ marginBottom: "0.5rem" }}>{desc}</div>
</>
),
[title, desc],
);
return (
<div>
{text}
<Speech text={text} />
</div>
);
}

export default function App() {
// 'news' holds response from some News API
const news = [
{ id: "1", title: "First random title.", desc: "First random description." },
{ id: "2", title: "Second random title.", desc: "Second random description." },
{ id: "3", title: "Third random title.", desc: "Third random description." },
];

return (
<div style={{ display: "flex", flexDirection: "column", rowGap: "1rem" }}>
{news.map(({ id, title, desc }) => (
<NewsItem key={id} title={title} desc={desc} />
))}
</div>
);
}

Full Customization

Using Function as Children(FaC) in the <Speech> component.

import React from "react";
import Speech from "react-text-to-speech";

export default function App() {
return (
<Speech text="This is a fully customized speech component." pitch={1.5} rate={2} volume={0.5} voiceURI="Microsoft Heera - English (India)">
{({ speechStatus, isInQueue, start, pause, stop }) => (
<div style={{ display: "flex", columnGap: "0.5rem" }}>
{speechStatus !== "started" ? <button onClick={start}>Start</button> : <button onClick={pause}>Pause</button>}
<button onClick={stop}>Stop</button>
</div>
)}
</Speech>
);
}

Usage with Markdown

Like useSpeech hook, the <Speech> component can also be used along with markdown. Refer Here

Custom MarkdownText Component
import parse from "html-react-parser";
import { useLayoutEffect, useMemo, useState } from "react";
import Markdown from "react-markdown";
import Speech, { HighlightedText } from "react-text-to-speech";
import remarkGfm from "remark-gfm";

function MarkdownText({ text }) {
const [showMarkdown, setShowMarkdown] = useState(true);
const [markdown, setMarkdown] = useState("");
const mdText = useMemo(() => <>{showMarkdown ? parse(markdown) : text}</>, [text, markdown]);

useLayoutEffect(() => {
setMarkdown(document.querySelector(".rtts-markdown")?.innerHTML);
}, [text, showMarkdown]);

function toggleMarkdown() {
stop();
setTimeout(() => setShowMarkdown((prev) => !prev), 1);
}

return (
<div className="flex flex-col space-y-3 p-4 text-justify">
<div className="flex w-fit flex-col items-center space-y-2">
<button className="rounded-sm border-2 border-black bg-gray-100 px-1 py-0.5 text-sm" onClick={toggleMarkdown}>
Toggle Markdown
</button>
<Speech id="unique-id" text={mdText} highlightText={true} />
</div>
<HighlightedText
id="unique-id"
className="prose max-w-[90vw] overflow-x-scroll whitespace-pre-wrap break-words leading-snug *:my-0 *:w-max *:max-w-full prose-headings:my-1 prose-pre:w-full prose-li:my-0 prose-table:w-full prose-table:table-fixed prose-th:border prose-th:p-2 prose-td:border prose-td:p-2"
>
{mdText}
</HighlightedText>
{showMarkdown && (
<Markdown className="rtts-markdown hidden" remarkPlugins={[remarkGfm]}>
{text}
</Markdown>
)}
</div>
);
}

export default function App() {
return <MarkdownText text={`# react-text-to-speech\nThis library is awesome`} />;
}

API Reference

Check the API Reference for more details.