ai newsSa., 24. Okt.
EilmeldungMoonshot AI launches new flagship Kim K3.1 Pro model with 3T parameters

ElevenLabs + React: Building a Voice-Enabled UI

Why Voice‑First UI Matters Today If you’ve been watching the rise of voice assistants, you’ve probably noticed a shift from “nice‑to‑have” to “must‑have.” Users expect apps to respond instantly, and hearing a natural‑sounding voice can make a UI feel more personal, accessible, and engaging. Enter E

dev.toSamstag 02:19 · 24.10.5 Min. Lesezeit
Bild: dev.to

Wer die Entwicklung von Sprachassistenten verfolgt hat, wird wahrscheinlich bemerkt haben, wie sich diese von netten Zusatzfunktionen zu unverzichtbaren Features gewandelt haben. Nutzer erwarten inzwischen, dass Apps sofort reagieren, und eine natürlich klingende Stimme kann einer Benutzeroberfläche ein persönlicheres, zugänglicheres und ansprechenderes Gefühl verleihen.

Ins Spiel kommt ElevenLabs, eine Text-to-Speech-Plattform (TTS), die extrem realistische Stimmen liefert und sogar das Klonen der eigenen Stimme ermöglicht. Der Dienst ist API-first aufgebaut, was bedeutet, dass man ihn in jeden Frontend-Stack integrieren kann, auch in React, ohne sich mit schwerfälligen SDKs oder On-Premise-Modellen herumschlagen zu müssen.

In diesem Beitrag zeige ich Schritt für Schritt, wie man eine einfache sprachgesteuerte React-Komponente aufbaut, die:

Profi-Tipp: Wer mit Voice Cloning experimentieren möchte, kann in der ElevenLabs-Konsole eine kurze Aufnahme der eigenen Stimme hochladen. Die geklonte Stimme funktioniert genauso wie die mitgelieferten Modelle.

npx create-react-app voice-ui-demo cd voice-ui-demo npm install axios Enter fullscreen mode Exit fullscreen mode Wir verwenden axios für HTTP-Anfragen, weil es Streaming-Antworten gut verarbeitet, aber fetch funktioniert genauso gut.

// src/elevenlabs.js import axios from " axios "; const API_KEY = process. env. REACT_APP_ELEVENLABS_API_KEY; const BASE_URL = " https://api.elevenlabs.io/v1 "; export const generateSpeech = async ( text, voiceId = " EXAVITQu4vr4xnGd " ) => { const response = await axios ({ method: " post ", url: ` ${ BASE_URL } /text-to-speech/ ${ voiceId } `, headers: { " xi-api-key ": API_KEY, " Content-Type ": " application/json ", Accept: " audio/mpeg ", }, data: { text, // optional: Stimmeinstellungen wie stability & similarity_boost voice_settings: { stability: 0.75, similarity_boost: 0.85 }, }, responseType: " blob ", // wir wollen rohe Audiodaten }); return URL. createObjectURL ( response. data ); }; Enter fullscreen mode Exit fullscreen mode Hinweis: Ersetze REACT_APP_ELEVENLABS_API_KEY in deiner.env-Datei durch den Schlüssel, den du von ElevenLabs erhalten hast ( https://try.elevenlabs.io/kr07zfuqn1bp ). React fügt ihn beim Build automatisch ein.

// src/components/VoiceInput.jsx import { useState } from " react "; import { generateSpeech } from "../elevenlabs "; export default function VoiceInput () { const [ text, setText ] = useState ( "" ); const [ audioUrl, setAudioUrl ] = useState ( null ); const [ loading, setLoading ] = useState ( false ); const handleSpeak = async () => { if (! text. trim ()) return; setLoading ( true ); try { const url = await generateSpeech ( text ); setAudioUrl ( url ); } catch ( err ) { console. error ( " TTS error: ", err ); } finally { setLoading ( false ); } }; return ( < div style = { { maxWidth: " 480px ", margin: " auto ", padding: " 1rem " } } > < h2 > 🗣️ Talk to Your App </ h2 > < textarea rows = { 4 } placeholder = "Type something…" value = { text } onChange = { ( e ) => setText ( e. target. value ) } style = { { width: " 100% ", marginBottom: " 0.5rem " } } /> < button onClick = { handleSpeak } disabled = { loading } > { loading? " Generating… ": " Speak " } </ button > { audioUrl && ( < div style = { { marginTop: " 1rem " } } > < audio controls src = { audioUrl } /> </ div > ) } </ div > ); } Enter fullscreen mode Exit fullscreen mode Füge die Komponente zu App.js hinzu:

import VoiceInput from "./components/VoiceInput "; function App () { return ( < div className = "App" > < VoiceInput /> </ div > ); } export default App; Enter fullscreen mode Exit fullscreen mode Das ist alles: Tippe einen Satz ein, klicke auf Speak, und du hörst eine hochwertige Stimme, die von ElevenLabs erzeugt wird.

Wer die Wiedergabe schon starten möchte, bevor die gesamte Datei vollständig heruntergeladen ist, kann die Axios-Anfrage auf einen ReadableStream umstellen. Hier ein kurzer Entwurf:

export const streamSpeech = async ( text, voiceId = " EXAVITQu4vr4xnGd " ) => { const response = await fetch ( ` ${ BASE_URL } /text-to-speech/ ${ voiceId } `, { method: " POST ", headers: { " xi-api-key ": API_KEY, " Content-Type ": " application/json ", Accept: " audio/mpeg ", }, body: JSON. stringify ({ text, voice_settings: { stability: 0.75 } }), }); const reader = response. body. getReader (); const chunks = []; while ( true ) { const { done, value } = await reader. read (); if ( done ) break; chunks. push ( value ); } const blob = new Blob ( chunks, { type: " audio/mpeg " }); return URL. createObjectURL ( blob ); }; Enter fullscreen mode Exit fullscreen mode Tausche generateSpeech einfach gegen streamSpeech in der Komponente aus, und du wirst feststellen, dass die Audiowiedergabe fast sofort beginnt, ein echter UX-Vorteil bei längeren Textpassagen.

Da die API zustandslos ist, kann man einen Microservice aufsetzen, der die TTS-Funktion für mehrere Frontends bereitstellt, etwa für React, Flutter oder auch ein einfaches curl-Skript.

Wer den Endpunkt einfach nur testen möchte, ohne Code zu schreiben:

curl -X POST "https://api.elevenlabs.io/v1/text-to-speech/EXAVITQu4vr4xnGd" \ -H "xi-api-key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -H "Accept: audio/mpeg" \ -d '{"text":"Hello from ElevenLabs!", "voice_settings":{"stability":0.7}}' \ --output hello.mp3 Enter fullscreen mode Exit fullscreen mode Öffne hello.mp3, und du hörst dieselbe Stimme, die auch deine React-Komponente zum Leben erweckt hat.

ElevenLabs bietet einen großzügigen kostenlosen Tarif an (bis zu 10.000 Zeichen pro Monat). Danach erfolgt die Abrechnung nach Nutzung, und die API gibt einen 429 Too Many Requests Fehler zurück, sobald das Kontingent überschritten wird. Ein einfaches exponentielles Backoff oder eine clientseitige Warteschlange kann die Benutzeroberfläche reibungslos halten:

const delay = ( ms ) => new Promise (( res ) => setTimeout ( res, ms )); async function safeGenerate ( text ) { let attempts = 0; while ( attempts < 5 ) { try { return await generateSpeech ( text ); } catch ( err ) { if ( err. response?. status === 429 ) { await delay ( 2 ** attempts * 500 ); // back‑off attempts ++; } else { throw err; } } } } Enter fullscreen mode Exit fullscreen mode Fazit: Eine sprachgesteuerte Benutzeroberfläche in React zu bauen ist überraschend unkompliziert, wenn man ein solides TTS-Backend zur Verfügung hat. ElevenLabs bietet:

Probier es aus, experimentiere mit verschiedenen Stimmeinstellungen, und beobachte, wie schnell sich deine App lebendiger anfühlt.

Du möchtest deinem nächsten Projekt eine menschliche Note verleihen? Hol dir einen API-Schlüssel und leg direkt mit der Sprachgenerierung los: https://try.elevenlabs.io/kr07zfuqn1bp. Viel Spaß beim Programmieren!

Automatisch übersetzt. Das Original auf Englisch ist unten aufklappbar.

Original (Englisch) anzeigen

If you’ve been watching the rise of voice assistants, you’ve probably noticed a shift from “nice‑to‑have” to “must‑have.” Users expect apps to respond instantly, and hearing a natural‑sounding voice can make a UI feel more personal, accessible, and engaging.

Enter ElevenLabs, a text‑to‑speech (TTS) platform that delivers ultra‑realistic voices and even lets you clone your own. The service is API‑first, which means you can drop it into any front‑end stack—React included—without wrestling with heavy SDKs or on‑prem models.

In this post I’ll walk you through wiring up a simple voice‑enabled React component that:

Pro tip: If you want to experiment with voice cloning, upload a short sample of your own voice in the ElevenLabs console. The cloned voice works the same way as the built‑in models.

npx create-react-app voice-ui-demo cd voice-ui-demo npm install axios Enter fullscreen mode Exit fullscreen mode We’ll use axios for HTTP requests because it handles streaming responses nicely, but fetch works just as well.

// src/elevenlabs.js import axios from " axios "; const API_KEY = process. env. REACT_APP_ELEVENLABS_API_KEY; const BASE_URL = " https://api.elevenlabs.io/v1 "; export const generateSpeech = async ( text, voiceId = " EXAVITQu4vr4xnGd " ) => { const response = await axios ({ method: " post ", url: ` ${ BASE_URL } /text-to-speech/ ${ voiceId } `, headers: { " xi-api-key ": API_KEY, " Content-Type ": " application/json ", Accept: " audio/mpeg ", }, data: { text, // optional: voice settings like stability & similarity_boost voice_settings: { stability: 0.75, similarity_boost: 0.85 }, }, responseType: " blob ", // we want raw audio data }); return URL. createObjectURL ( response. data ); }; Enter fullscreen mode Exit fullscreen mode Note: Replace REACT_APP_ELEVENLABS_API_KEY in your.env file with the key you got from ElevenLabs ( https://try.elevenlabs.io/kr07zfuqn1bp ). React will automatically inject it at build time.

// src/components/VoiceInput.jsx import { useState } from " react "; import { generateSpeech } from "../elevenlabs "; export default function VoiceInput () { const [ text, setText ] = useState ( "" ); const [ audioUrl, setAudioUrl ] = useState ( null ); const [ loading, setLoading ] = useState ( false ); const handleSpeak = async () => { if (! text. trim ()) return; setLoading ( true ); try { const url = await generateSpeech ( text ); setAudioUrl ( url ); } catch ( err ) { console. error ( " TTS error: ", err ); } finally { setLoading ( false ); } }; return ( < div style = { { maxWidth: " 480px ", margin: " auto ", padding: " 1rem " } } > < h2 > 🗣️ Talk to Your App </ h2 > < textarea rows = { 4 } placeholder = "Type something…" value = { text } onChange = { ( e ) => setText ( e. target. value ) } style = { { width: " 100% ", marginBottom: " 0.5rem " } } /> < button onClick = { handleSpeak } disabled = { loading } > { loading? " Generating… ": " Speak " } </ button > { audioUrl && ( < div style = { { marginTop: " 1rem " } } > < audio controls src = { audioUrl } /> </ div > ) } </ div > ); } Enter fullscreen mode Exit fullscreen mode Add the component to App.js:

import VoiceInput from "./components/VoiceInput "; function App () { return ( < div className = "App" > < VoiceInput /> </ div > ); } export default App; Enter fullscreen mode Exit fullscreen mode That’s it—type a sentence, hit Speak, and you’ll hear a high‑fidelity voice rendered by ElevenLabs.

If you want to start playback before the whole file finishes downloading, you can switch the Axios call to a ReadableStream. Here’s a quick sketch:

export const streamSpeech = async ( text, voiceId = " EXAVITQu4vr4xnGd " ) => { const response = await fetch ( ` ${ BASE_URL } /text-to-speech/ ${ voiceId } `, { method: " POST ", headers: { " xi-api-key ": API_KEY, " Content-Type ": " application/json ", Accept: " audio/mpeg ", }, body: JSON. stringify ({ text, voice_settings: { stability: 0.75 } }), }); const reader = response. body. getReader (); const chunks = []; while ( true ) { const { done, value } = await reader. read (); if ( done ) break; chunks. push ( value ); } const blob = new Blob ( chunks, { type: " audio/mpeg " }); return URL. createObjectURL ( blob ); }; Enter fullscreen mode Exit fullscreen mode Swap generateSpeech with streamSpeech in the component and you’ll notice the audio starts playing almost instantly—a nice UX win for longer passages.

Because the API is stateless, you can spin up a micro‑service that handles TTS for multiple front‑ends—React, Flutter, or even a simple curl script.

If you just want to test the endpoint without writing code:

curl -X POST "https://api.elevenlabs.io/v1/text-to-speech/EXAVITQu4vr4xnGd" \ -H "xi-api-key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -H "Accept: audio/mpeg" \ -d '{"text":"Hello from ElevenLabs!", "voice_settings":{"stability":0.7}}' \ --output hello.mp3 Enter fullscreen mode Exit fullscreen mode Open hello.mp3 and you’ll hear the same voice that powered your React component.

ElevenLabs offers a generous free tier (up to 10 k characters per month). After that, pricing is pay‑as‑you‑go, and the API returns 429 Too Many Requests when you exceed your quota. A simple exponential back‑off or a client‑side queue can keep the UI smooth:

const delay = ( ms ) => new Promise (( res ) => setTimeout ( res, ms )); async function safeGenerate ( text ) { let attempts = 0; while ( attempts < 5 ) { try { return await generateSpeech ( text ); } catch ( err ) { if ( err. response?. status === 429 ) { await delay ( 2 ** attempts * 500 ); // back‑off attempts ++; } else { throw err; } } } } Enter fullscreen mode Exit fullscreen mode Wrapping Up Building a voice‑enabled UI in React is surprisingly straightforward when you have a solid TTS backend. ElevenLabs provides:

Give it a spin, experiment with different voice settings, and watch how quickly your app feels more alive.

Ready to add a human touch to your next project? Grab an API key and start generating speech right now: https://try.elevenlabs.io/kr07zfuqn1bp. Happy coding!

Quelle: dev.to (dev.to). Original öffnen