DEV Community

VoiceDeveloper
VoiceDeveloper

Posted on

How to Use ElevenLabs with WordPress

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.

ElevenLabs – Try it now!


Getting Started: API Key & Installation

  1. Sign up at the link above and grab your API key from the dashboard → API → Your API key.
  2. 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');
Enter fullscreen mode Exit fullscreen mode

Security note: Never commit the raw key to a public repo. Use wp-config.php or 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 );
}
Enter fullscreen mode Exit fullscreen mode

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 )
    );
});
Enter fullscreen mode Exit fullscreen mode

Now you can embed a simple shortcode anywhere:

[tts]Your article's first paragraph goes here.[/tts]
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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:

  1. Hash the text (md5($text)) and use it as part of the filename.
  2. Check if the file exists before calling the API.
  3. 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 );
}
Enter fullscreen mode Exit fullscreen mode

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:

  1. Upload samples via the dashboard or the /v1/voices/add endpoint.
  2. Retrieve the newly created voice_id.
  3. Use that voice_id in the same el_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"
Enter fullscreen mode Exit fullscreen mode

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:

Try ElevenLabs now!

Top comments (0)