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:
Top comments (0)