Why Add Text‑to‑Speech to WordPress?
If you’ve ever built a blog, an e‑learning portal, or a product showcase, you know that content accessibility is a moving target. Screen readers help, but they’re not always the most engaging way to present long‑form text. Adding a natural‑sounding voice that reads your articles out loud can:
- Boost SEO (Google loves rich media)
- Increase time‑on‑page for users who prefer listening
- Make your site more inclusive for visually impaired visitors
- Open up new revenue streams (audio subscriptions, podcasts, etc.)
Enter ElevenLabs – a state‑of‑the‑art voice AI platform that delivers lifelike speech synthesis and voice cloning. With a simple REST API you can generate audio on‑the‑fly, cache it, and embed it anywhere in your WordPress theme or Gutenberg block.
Pro tip: The affiliate link below gives you a free trial and a generous credit pool to experiment without breaking the bank.
Getting Started: API Key & Installation
- Sign up at the link above and grab your API key from the dashboard → API → Your API key.
- Install a lightweight plugin like Code Snippets (or add the code directly to your child theme’s
functions.php). This keeps your custom PHP tidy and avoids core modifications.
// functions.php – store API key safely (you could also use WP env vars) define('ELEVENLABS_API_KEY', 'YOUR_API_KEY_HERE'); Security note: Never commit the raw key to a public repo. Use
wp-config.phpor environment variables on production.
Generating Speech with PHP (cURL)
WordPress runs on PHP, so the most straightforward integration is a server‑side request that returns an MP3 file. Below is a reusable function that calls the ElevenLabs /v1/text-to-speech/{voice_id} endpoint.
/** * Convert $text to speech using ElevenLabs and return the MP3 URL. * * @param string $text The text you want spoken. * @param string $voice The voice ID (e.g., "EXAVITQu4vr4xnSDxMaL"). * @return string|WP_Error URL to the cached MP3 or WP_Error on failure. */ function el_generate_speech( $text, $voice = 'EXAVITQu4vr4xnSDxMaL' ) { $endpoint = "https://api.elevenlabs.io/v1/text-to-speech/{$voice}"; $payload = [ 'text' => $text, 'voice_settings' => [ 'stability' => 0.75, 'similarity_boost' => 0.85, ], ]; $args = [ 'headers' => [ 'Accept' => 'audio/mpeg', 'Content-Type' => 'application/json', 'xi-api-key' => ELEVENLABS_API_KEY, ], 'body' => wp_json_encode( $payload ), 'timeout' => 30, 'method' => 'POST', ]; $response = wp_remote_post( $endpoint, $args ); if ( is_wp_error( $response ) ) { return $response; // bubble up the error } // Save MP3 to the uploads folder $upload_dir = wp_upload_dir(); $filename = sanitize_title( $text ) . '.mp3'; $file_path = trail_concat( $upload_dir['path'], '/', $filename ); file_put_contents( $file_path, wp_remote_retrieve_body( $response ) ); // Return the public URL return trail_concat( $upload_dir['url'], '/', $filename ); } How to use it in a post
add_shortcode( 'tts', function( $atts, $content = '' ) { $audio_url = el_generate_speech( $content ); if ( is_wp_error( $audio_url ) ) { return '<p>❌ Speech generation failed.</p>'; } return sprintf( '<audio controls src="%s"></audio>', esc_url( $audio_url ) ); }); Now you can embed a simple shortcode anywhere:
[tts]Your article's first paragraph goes here.[/tts] WordPress will render an <audio> player with the freshly generated voice.
Front‑End Option: JavaScript + Fetch
If you prefer not to hit the API from your server (e.g., you want instant previews in the Gutenberg editor), you can call ElevenLabs directly from the browser. Caution: expose the API key only to trusted users or use a short‑lived token generated server‑side.
<button id="speakBtn">Listen to this paragraph</button> <audio id="audioPlayer" controls></audio> <script> document.getElementById('speakBtn').addEventListener('click', async () => { const text = "ElevenLabs makes voice AI feel magical."; const voiceId = "EXAVITQu4vr4xnSDxMaL"; const response = await fetch( `https://api.elevenlabs.io/v1/text-to-speech/${voiceId}`, { method: "POST", headers: { "Content-Type": "application/json", "xi-api-key": "YOUR_API_KEY_HERE", "Accept": "audio/mpeg" }, body: JSON.stringify({ text, voice_settings: { stability: 0.7, similarity_boost: 0.9 } }) } ); if (!response.ok) { console.error("API error:", response.statusText); return; } const blob = await response.blob(); const url = URL.createObjectURL(blob); const player = document.getElementById('audioPlayer'); player.src = url; player.play(); }); </script> This snippet is perfect for a custom Gutenberg block that lets content editors preview speech before publishing.
Caching & Performance
Generating audio on every page load defeats the purpose of a fast site. Here’s a quick caching strategy:
- Hash the text (
md5($text)) and use it as part of the filename. - Check if the file exists before calling the API.
- Set an expiration (e.g., 30 days) and delete old files via a cron job.
function el_cached_speech_url( $text ) { $hash = md5( $text ); $filename = "tts-{$hash}.mp3"; $upload_dir = wp_upload_dir(); $file_path = trail_concat( $upload_dir['path'], '/', $filename ); if ( file_exists( $file_path ) ) { return trail_concat( $upload_dir['url'], '/', $filename ); } // Not cached – generate and store return el_generate_speech( $text ); } Now replace the earlier el_generate_speech() call with el_cached_speech_url() in your shortcode.
Going Further: Voice Cloning
ElevenLabs also offers voice cloning – upload a few minutes of a speaker’s audio, and the service creates a custom voice model you can reuse. The workflow is similar:
- Upload samples via the dashboard or the
/v1/voices/addendpoint. - Retrieve the newly created
voice_id. - Use that
voice_idin the sameel_generate_speech()function.
curl -X POST "https://api.elevenlabs.io/v1/voices/add" \ -H "xi-api-key: YOUR_API_KEY_HERE" \ -F "name=My Custom Voice" \ -F "files[]=@/path/to/sample1.wav" \ -F "files[]=@/path/to/sample2.wav" The response will contain the voice_id you can store in a custom option (update_option('my_custom_voice_id', $id)) and reference in future TTS calls.
Wrapping Up
Integrating ElevenLabs into WordPress is surprisingly painless:
- A few lines of PHP give you server‑side synthesis and caching.
- A lightweight JavaScript snippet lets editors preview speech instantly.
- Voice cloning opens doors to brand‑specific narrators without hiring voice talent.
All of this runs on the same robust API that powers podcasts, audiobooks, and interactive assistants. Give it a spin on a test post, measure the uplift in engagement, and iterate from there.
Ready to give your WordPress site a voice?
Grab your free credits and start generating lifelike audio today with ElevenLabs: