@cheap-tts/react
v0.2.0
Published
React provider and hooks for the Cheap TTS browser SDK
Maintainers
Readme
Cheap TTS React SDK
React Provider and hooks for the Cheap TTS Browser SDK. It manages the browser client lifecycle, voice catalog, progress state, synthesis results, and generated audio URLs.
An active Cheap TTS subscription and a browser publishable key are required.
npm install @cheap-tts/reactimport { CheapTtsProvider, useCheapTts, useCheapTtsSynthesis } from "@cheap-tts/react";
export function App() {
return (
<CheapTtsProvider publishableKey="pk_live_your_project">
<VoiceGenerator />
</CheapTtsProvider>
);
}
function VoiceGenerator() {
const { voices, status: catalogStatus } = useCheapTts();
const { synthesize, audioUrl, progress, isSynthesizing, error } = useCheapTtsSynthesis();
async function generate() {
await synthesize({
text: "Xin chào từ Cheap TTS.",
voice: "vi-entertainment",
rate: 1,
}).catch(() => undefined); // The hook exposes the error state below.
}
return (
<div>
<p>{catalogStatus === "loading" ? "Loading voices…" : `${voices.length} voices`}</p>
<button onClick={generate} disabled={isSynthesizing}>Generate</button>
{progress && <p>{progress.stage}: {progress.progress ?? "working"}</p>}
{error && <p role="alert">{error.message}</p>}
{audioUrl && <audio controls src={audioUrl} />}
</div>
);
}API
CheapTtsProvidercreates and destroys the underlying browser client. It is safe to render during SSR because the client starts only after mount, and the package includes the Next.js"use client"boundary.useCheapTts()exposesclient,voices, catalogstatus,error,refreshVoices(), andclearError().useCheapTtsSynthesis()exposessynthesize(), progress and error state, the latest result, and anaudioUrlthat is automatically revoked when replaced or unmounted.useCheapTtsVoice(voice)preloads one voice, aborts loading on unmount or voice change, and exposesretry().
The wrapper accepts the same apiBase, workerUrl, vendorBase, and telemetry options as @cheap-tts/browser-sdk.
Reading pauses
Pauses are left to the voice model by default. Pass pauses to insert real silence after a punctuation mark instead, in seconds (0–2):
await synthesize({
text,
voice: "vi-entertainment",
pauses: { sentence: 0.4, paragraph: 0.8 },
});Fields: sentence, comma, ellipsis, paragraph (a blank line). Every field is optional and defaults to 0, meaning the model's own pause — so omitting pauses keeps the audio you get today. Raising a value costs generation speed, because the audio has to be cut at that boundary for silence to follow it.
