DEV Community

VoiceDeveloper
VoiceDeveloper

Posted on

How to Use ElevenLabs with WordPress

Adding realistic, human‑like audio to a WordPress site used to mean hiring voice actors or juggling bulky plugins. Today you can generate high‑quality speech on‑the‑fly with a simple API call, and ElevenLabs makes it effortless. In this post I’ll walk you through wiring the ElevenLabs text‑to‑speech (TTS) service into WordPress, from grabbing an API key to building a reusable shortcode that any editor can drop into a post.

Why Add Voice to WordPress?

  • Accessibility – Screen readers are great, but a natural‑sounding narration can help users with low literacy or visual impairments.
  • Engagement – Readers stay longer when they can listen while they scroll, especially on mobile.
  • SEO boost – Search engines love rich media; a transcript + audio pair can improve rankings.

If you’ve ever wanted to turn blog posts, product descriptions, or FAQs into audio without recording a single word, this guide is for you.

Getting Started with ElevenLabs

First things first: sign up for an account at the official ElevenLabs platform. Their free tier gives you a generous number of characters per month, which is plenty for testing.

👉 Try it now: https://try.elevenlabs.io/kr07zfuqn1bp

Once you’ve confirmed your email, head to the API keys section of the dashboard and generate a new secret key. Keep this key safe; you’ll need it for every request you make from WordPress.

Setting Up API Access in WordPress

You have a few options for making HTTP requests from WordPress:

  1. wp_remote_post() – the built‑in WordPress HTTP API.
  2. cURL – if you prefer raw PHP.
  3. JavaScript fetch – for front‑end interactions.

Below are examples for each, so you can pick the style that fits your workflow.

1. cURL Example (PHP)

<?php
function elevenlabs_tts_curl( $text, $voice = 'Bella' ) {
    $api_key = 'YOUR_ELEVENLABS_API_KEY';
    $url = "https://api.elevenlabs.io/v1/text-to-speech/{$voice}";

    $payload = [
        'text' => $text,
        'model_id' => 'eleven_monolingual_v1',
        'voice_settings' => [
            'stability' => 0.75,
            'similarity_boost' => 0.85,
        ],
    ];

    $ch = curl_init( $url );
    curl_setopt( $ch, CURLOPT_POST, true );
    curl_setopt( $ch, CURLOPT_HTTPHEADER, [
        "xi‑api‑key: {$api_key}",
        'Content-Type: application/json',
    ]);
    curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
    curl_setopt( $ch, CURLOPT_POSTFIELDS, json_encode( $payload ) );

    $response = curl_exec( $ch );
    $httpcode = curl_getinfo( $ch, CURLINFO_HTTP_CODE );
    curl_close( $ch );

    if ( $httpcode !== 200 ) {
        error_log( "ElevenLabs API error: {$response}" );
        return false;
    }

    // The API returns base64‑encoded audio
    $data = json_decode( $response, true );
    return base64_decode( $data['audio_content'] );
}
?>
Enter fullscreen mode Exit fullscreen mode

Note: Replace YOUR_ELEVENLABS_API_KEY with the key you created earlier. The function returns raw MP3 data that you can write to a file or stream directly.

2. Using WordPress HTTP API (wp_remote_post)

function elevenlabs_tts_wp( $text, $voice = 'Bella' ) {
    $api_key = 'YOUR_ELEVENLABS_API_KEY';
    $endpoint = "https://api.elevenlabs.io/v1/text-to-speech/{$voice}";

    $body = [
        'text' => $text,
        'model_id' => 'eleven_monolingual_v1',
        'voice_settings' => [
            'stability' => 0.75,
            'similarity_boost' => 0.85,
        ],
    ];

    $args = [
        'headers' => [
            'xi-api-key'   => $api_key,
            'Content-Type' => 'application/json',
        ],
        'body'    => wp_json_encode( $body ),
        'timeout' => 30,
    ];

    $response = wp_remote_post( $endpoint, $args );

    if ( is_wp_error( $response ) ) {
        error_log( $response->get_error_message() );
        return false;
    }

    $data = json_decode( wp_remote_retrieve_body( $response ), true );
    return base64_decode( $data['audio_content'] );
}
Enter fullscreen mode Exit fullscreen mode

Both snippets do the same thing – they send the text to ElevenLabs, receive a base64‑encoded MP3, and decode it for further use.

Turning the Audio into a WordPress Shortcode

Now that we have a PHP function that returns raw MP3 data, let’s wrap it in a shortcode so any editor can add audio with a simple tag:

function elevenlabs_audio_shortcode( $atts, $content = '' ) {
    $a = shortcode_atts( [
        'voice' => 'Bella',
    ], $atts );

    // Sanitize the content
    $text = wp_strip_all_tags( $content );

    // Generate the audio file (store in uploads folder)
    $audio = elevenlabs_tts_wp( $text, $a['voice'] );
    if ( ! $audio ) {
        return '<p>Sorry, we could not generate audio.</p>';
    }

    $upload_dir = wp_upload_dir();
    $filename   = 'tts-' . wp_hash( $text ) . '.mp3';
    $file_path  = $upload_dir['path'] . '/' . $filename;

    // Save the MP3 file
    file_put_contents( $file_path, $audio );

    // Build the URL for the <audio> tag
    $file_url = $upload_dir['url'] . '/' . $filename;

    return sprintf(
        '<audio controls src="%s"></audio>',
        esc_url( $file_url )
    );
}
add_shortcode( 'tts', 'elevenlabs_audio_shortcode' );
Enter fullscreen mode Exit fullscreen mode

Usage in the editor

[tts voice="Arnold"]
Welcome to our new product line. This audio will be generated on the fly using ElevenLabs.
[/tts]
Enter fullscreen mode Exit fullscreen mode

When the post is rendered, WordPress calls the shortcode, contacts the ElevenLabs API, saves the MP3 to the uploads directory, and injects a native HTML5 <audio> player.

Front‑End Fetch Example (JavaScript)

If you’d rather keep the API secret on the server and just fetch the ready‑made audio file via AJAX, you can expose a tiny endpoint:

// functions.php
add_action( 'rest_api_init', function () {
    register_rest_route( 'elevenlabs/v1', '/speak', [
        'methods'  => 'POST',
        'callback' => 'elevenlabs_rest_speak',
        'permission_callback' => '__return_true',
    ] );
} );

function elevenlabs_rest_speak( WP_REST_Request $request ) {
    $text  = $request->get_param( 'text' );
    $voice = $request->get_param( 'voice' ) ?: 'Bella';
    $audio = elevenlabs_tts_wp( $text, $voice );

    if ( ! $audio ) {
        return new WP_Error( 'tts_failed', 'Audio generation failed', [ 'status' => 500 ] );
    }

    // Return raw MP3 with proper header
    return new WP_REST_Response( $audio, 200, [
        'Content-Type' => 'audio/mpeg',
    ] );
}
Enter fullscreen mode Exit fullscreen mode

Now the front‑end can request audio without ever exposing the API key:

<button id="speakBtn">Listen to this paragraph</button>

<script>
document.getElementById('speakBtn').addEventListener('click', async () => {
    const text = `Your paragraph goes here. It will be spoken by ElevenLabs.`;
    const response = await fetch('/wp-json/elevenlabs/v1/speak', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ text, voice: 'Bella' })
    });

    if (!response.ok) {
        console.error('TTS failed');
        return;
    }

    const blob = await response.blob();
    const url = URL.createObjectURL(blob);
    const audio = new Audio(url);
    audio.play();
});
</script>
Enter fullscreen mode Exit fullscreen mode

This approach keeps the heavy lifting on the server while giving visitors a seamless, click‑to‑listen experience.

Voice Cloning & Fine‑Tuning

ElevenLabs also offers voice cloning: upload a few minutes of a speaker’s recordings, and the service will generate a custom voice model. The workflow is the same—just replace the voice ID with the ID of your cloned model. When you’re ready to go beyond the default voices, check out the cloning docs on the ElevenLabs dashboard.

Best Practices & Gotchas

Issue Recommendation
Rate limits Cache generated MP3s (as we did in the shortcode) to avoid repeated calls for the same text.
Long articles Split content into logical sections (e.g., per paragraph) to stay under the character limit per request.
Accessibility Always provide a transcript alongside the audio for users who can’t or don’t want to listen.
Security Never expose the API key to the browser. Use server‑side functions or a custom REST endpoint as shown above.

Wrap‑Up

Integrating AI‑powered speech into WordPress is now a matter of a few lines of code. By leveraging ElevenLabs’s high‑fidelity TTS engine, you can turn any piece of content into an engaging audio experience without leaving the comfort of your WordPress admin.

Ready to give your site a voice? Grab your API key, drop the snippets into your theme or plugin, and start experimenting.

Give ElevenLabs a spin today: https://try.elevenlabs.io/kr07zfuqn1bp

Happy coding!

Top comments (0)