Add this component

npx zentauri-ui add speech-synthesizer

Accessibility notes

Keyboard accessible by default with semantic markup, visible focus treatment, and tokenized states. Add descriptive labels for icon-only or decorative usage.

Dependency notes

Check Installation for shared peers. This component keeps styling in Tailwind classes and the --zui-* token contract.

Media

Speech Synthesizer for text-to-speech

Use the speech synthesizer component to convert text to spoken audio in the browser. Built on the Web Speech API, it provides play, pause, resume, and stop controls with configurable rate, pitch, and volume settings.

Hello, welcome to Zentauri UI

Speech synthesis at your fingertips

Speech synthesizer variants playground

Pick an appearance and size to preview the speech synthesizer component live. Toggle Show output / Show code and the snippet updates to match the selected variant.


Speech synthesis demo

All appearances

Every shipped appearance token at a glance. Click any swatch to load it into the playground above.

default

...

subtle

...

muted

...

primary

...

blue

...

cyan

...

green

...

lime

...

emerald

...

indigo

...

purple

...

pink

...

rose

...

sky

...

teal

...

yellow

...

orange

...

red

...

slate

...

gray

...

zinc

...

Speech Synthesizer API

Generated from the package prop types and variant definitions.

SpeechSynthesizer

SpeechSynthesizerProps

Variants

PropTypeDefault
size
lgmdsm
md

Behavior

PropTypeDefault
appearance'default' | 'blue' | 'cyan' | 'green' | 'lime' | 'red' | 'slate' | 'zinc' | 'sky' | 'rose' | 'purple' | 'pink' | 'orange' | 'yellow' | 'teal' | 'indigo' | 'emerald' | 'gray' | 'subtle' | 'muted' | 'primary' | null | undefinednone
autoSpeakboolean | undefinednone
langstring | undefinednone
onEnd(() => void) | undefinednone
onError((error: string) => void) | undefinednone
onStart(() => void) | undefinednone
onStateChange((state: SpeechSynthesizerState) => void) | undefinednone
pitchnumber | undefinednone
ratenumber | undefinednone
renderPause((props: { isSpeaking: boolean; isPaused: boolean; state: SpeechSynthesizerState; }) => React.ReactNode) | undefinednone
renderPlay((props: { isSpeaking: boolean; isPaused: boolean; state: SpeechSynthesizerState; }) => React.ReactNode) | undefinednone
renderStop((props: { isSpeaking: boolean; isPaused: boolean; state: SpeechSynthesizerState; }) => React.ReactNode) | undefinednone
showProgressboolean | undefinednone
textstring | undefinednone
volumenumber | undefinednone

Content

PropTypeDefault
childrenReactNodenone
Inherited HTML props
PropTypeDefault
classNamestring | undefinednone
idstring | undefinednone
onClickMouseEventHandler<HTMLDivElement> | undefinednone
styleCSSProperties | undefinednone
titlestring | undefinednone

SpeechSynthesizerVariant

SpeechSynthesizerVariantProps

Behavior

PropTypeDefault
appearance'default' | 'blue' | 'cyan' | 'green' | 'lime' | 'red' | 'slate' | 'zinc' | 'sky' | 'rose' | 'purple' | 'pink' | 'orange' | 'yellow' | 'teal' | 'indigo' | 'emerald' | 'gray' | 'subtle' | 'muted' | 'primary' | null | undefinednone
size'md' | 'sm' | 'lg' | null | undefinednone

SpeechSynthesizerAnimated

SpeechSynthesizerAnimatedProps

animated

Behavior

PropTypeDefault
animationSpeechSynthesizerAnimation | undefinednone
appearance'default' | 'blue' | 'cyan' | 'green' | 'lime' | 'red' | 'slate' | 'zinc' | 'sky' | 'rose' | 'purple' | 'pink' | 'orange' | 'yellow' | 'teal' | 'indigo' | 'emerald' | 'gray' | 'subtle' | 'muted' | 'primary' | null | undefinednone
autoSpeakboolean | undefinednone
langstring | undefinednone
onEnd(() => void) | undefinednone
onError((error: string) => void) | undefinednone
onStart(() => void) | undefinednone
onStateChange((state: SpeechSynthesizerState) => void) | undefinednone
pitchnumber | undefinednone
ratenumber | undefinednone
refAllows getting a ref to the component instance. Once the component unmounts, React will set `ref.current` to `null` (or call the ref with `null` if you passed a callback ref).Ref<HTMLDivElement> | undefinednone
renderPause((props: { isSpeaking: boolean; isPaused: boolean; state: SpeechSynthesizerState; }) => React.ReactNode) | undefinednone
renderPlay((props: { isSpeaking: boolean; isPaused: boolean; state: SpeechSynthesizerState; }) => React.ReactNode) | undefinednone
renderStop((props: { isSpeaking: boolean; isPaused: boolean; state: SpeechSynthesizerState; }) => React.ReactNode) | undefinednone
showProgressboolean | undefinednone
size'md' | 'sm' | 'lg' | null | undefinednone
textstring | undefinednone
volumenumber | undefinednone

Content

PropTypeDefault
childrenReactNodenone
Inherited HTML props
PropTypeDefault
classNamestring | undefinednone
idstring | undefinednone
onClickMouseEventHandler<HTMLDivElement> | undefinednone
styleCSSProperties | undefinednone
titlestring | undefinednone
CSS variable overrides

Speech Synthesizer CSS variables

Override these speech synthesizer variables on :root, a theme selector, or a component wrapper.

50 variables

Pattern: --zui-<component>-<slot?>-<variant?>-<property>-<state?>-dark?

:root {
  --zui-speech-synthesizer-default-btn-bg: oklch(20.8% 0.042 265.755);
  --zui-speech-synthesizer-subtle-btn-bg: oklch(92.9% 0.013 255.508);
  --zui-speech-synthesizer-muted-btn-bg: oklch(44.6% 0.043 257.281);
  --zui-speech-synthesizer-primary-btn-bg: oklch(20.8% 0.042 265.755);
  --zui-speech-synthesizer-blue-btn-bg: #2563eb;
  --zui-speech-synthesizer-cyan-btn-bg: #0891b2;
  --zui-speech-synthesizer-green-btn-bg: #16a34a;
  --zui-speech-synthesizer-lime-btn-bg: #65a30d;
  --zui-speech-synthesizer-emerald-btn-bg: oklch(69.6% 0.17 162.48);
  --zui-speech-synthesizer-indigo-btn-bg: oklch(39.8% 0.195 277.366);
  --zui-speech-synthesizer-purple-btn-bg: oklch(43.8% 0.218 303.724);
  --zui-speech-synthesizer-pink-btn-bg: oklch(45.9% 0.187 3.815);
  --zui-speech-synthesizer-rose-btn-bg: oklch(64.5% 0.246 16.439);
  --zui-speech-synthesizer-sky-btn-bg: oklch(68.5% 0.169 237.323);
  --zui-speech-synthesizer-teal-btn-bg: oklch(70.4% 0.14 182.503);
  --zui-speech-synthesizer-yellow-btn-bg: oklch(79.5% 0.184 86.047);
  --zui-speech-synthesizer-orange-btn-bg: oklch(70.5% 0.213 47.604);
  --zui-speech-synthesizer-red-btn-bg: #dc2626;
  --zui-speech-synthesizer-slate-btn-bg: #475569;
  --zui-speech-synthesizer-gray-btn-bg: oklch(55.1% 0.027 264.364);
  --zui-speech-synthesizer-zinc-btn-bg: #52525b;
  --zui-speech-synthesizer-btn-fg: #ffffff;
  --zui-speech-synthesizer-text-fg: oklch(20.8% 0.042 265.755);
  --zui-speech-synthesizer-active-ring: #16a34a;
  --zui-speech-synthesizer-track-bg: #0000001a;
}

/* Dark theme variables follow the same names with -dark appended. */
.dark {
  --zui-speech-synthesizer-default-btn-bg-dark: oklch(98.4% 0.003 247.858);
  --zui-speech-synthesizer-subtle-btn-bg-dark: oklch(27.9% 0.041 260.031);
}

Composition and API

The Speech Synthesizer component wraps the browser's SpeechSynthesis API. It exposes speak, pause, resume, and stop methods via an imperative ref handle. The component provides onStart, onEnd, onError, and onStateChange callbacks for integrating speech synthesis into your application state.

Accessibility

The control buttons use aria-labels for screen readers. The component announces state changes via the onStateChange callback. Ensure you provide visual alternatives for speech output, and respect user preferences for reduced motion.

Next.js integration notes

The Web Speech API is browser-only. Import the component via dynamic import with ssr: false to avoid server-side errors. The component handles SSR safety internally with a typeof window guard, but dynamic import is recommended for Next.js apps.

FAQ

Which browsers support speech synthesis?

The SpeechSynthesis API is widely supported across Chrome, Firefox, Safari, and Edge. Voice availability varies by browser and operating system.

How do I change the voice?

Use the lang prop to set the language. The browser selects the default voice for the given locale. Custom voice selection is available via the underlying SpeechSynthesis API.

Can I control speed and pitch?

Yes. Use the rate prop (0.1 to 10, default 1) and pitch prop (0 to 2, default 1) to adjust speech characteristics.