DEV Community

VoiceDeveloper
VoiceDeveloper

Posted on

How to Add AI Voice Narration to Your WordPress Blog

Overview

Adding AI‑generated voice narration to your WordPress posts can boost accessibility, keep readers on your site longer, and give your blog a futuristic edge. In this guide we’ll walk through the entire pipeline:

  1. Generate speech with ElevenLabs – a state‑of‑the‑art text‑to‑speech (TTS) service that also offers voice cloning.
  2. Store the audio files on your server (or a CDN).
  3. Inject an HTML5 audio player into your WordPress post automatically.

We’ll also cover deployment basics and why Bluehost is a simple, affordable way to host the small Flask app that talks to the ElevenLabs API.


Prerequisites

What you need Why
A WordPress site (self‑hosted) To embed the audio player.
A hosting account – we recommend Bluehost One‑click WordPress install + cheap PHP/Node/Python support.
An ElevenLabs account (free tier works) Provides the TTS endpoint and voice cloning.
Basic knowledge of Python (or JavaScript) and the WordPress editor To follow the code examples.
curl (optional) Quick test of the API without writing code.

1. Grab Your ElevenLabs API Key

  1. Sign up at ElevenLabs.
  2. In the dashboard, go to API → Keys and copy the generated key.

Tip: Keep the key secret – treat it like a password. Store it in an environment variable (ELEVENLABS_API_KEY) on your server.


2. Set Up a Tiny Flask Service (Python)

We'll create a micro‑service that receives a piece of text, calls the ElevenLabs API, and returns the URL of the generated MP3. This keeps your WordPress site lightweight – it only needs to embed the audio tag.

# On your Bluehost server (or local dev box)
python3 -m venv venv
source venv/bin/activate
pip install Flask requests python-dotenv
Enter fullscreen mode Exit fullscreen mode

Create a file called app.py:

import os
from flask import Flask, request, jsonify
import requests
from dotenv import load_dotenv

load_dotenv()                     # loads ELEVENLABS_API_KEY from .env
API_KEY = os.getenv("ELEVENLABS_API_KEY")
VOICE_ID = "EXAVITQu4vr4xnSDxMaL"  # default voice; replace with your clone if you have one

app = Flask(__name__)

@app.route("/tts", methods=["POST"])
def tts():
    data = request.get_json()
    text = data.get("text")
    if not text:
        return jsonify({"error": "Missing 'text'"}), 400

    # Call ElevenLabs TTS endpoint
    url = f"https://api.elevenlabs.io/v1/text-to-speech/{VOICE_ID}"
    headers = {
        "xi-api-key": API_KEY,
        "Content-Type": "application/json"
    }
    payload = {
        "text": text,
        "model_id": "eleven_monolingual_v1",
        "voice_settings": {"stability": 0.75, "similarity_boost": 0.85}
    }

    response = requests.post(url, json=payload, headers=headers)
    if response.status_code != 200:
        return jsonify({"error": "ElevenLabs request failed"}), 500

    # Save the MP3 locally (you could also stream it directly)
    filename = f"static/{hash(text)}.mp3"
    with open(filename, "wb") as f:
        f.write(response.content)

    audio_url = request.host_url + filename
    return jsonify({"audio_url": audio_url})

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000)
Enter fullscreen mode Exit fullscreen mode

Create a .env file (never commit this to git):

ELEVENLABS_API_KEY=your_real_key_here
Enter fullscreen mode Exit fullscreen mode

Deploy the Flask app on your Bluehost account:

  • Use the One‑Click Python App in the Bluehost cPanel or set up a simple systemd service.
  • Point a subdomain like voice.yourdomain.com to the app’s port (5000) using a reverse proxy (Bluehost’s Apache/Nginx config can handle this).

Now you have an endpoint https://voice.yourdomain.com/tts that returns an MP3 URL for any text you send.


3. Quick curl Test

Before wiring WordPress, make sure the service works:

curl -X POST https://voice.yourdomain.com/tts \
  -H "Content-Type: application/json" \
  -d '{"text":"Hello, WordPress readers! This post is now narrated by AI."}'
Enter fullscreen mode Exit fullscreen mode

You should receive a JSON response:

{
  "audio_url": "https://voice.yourdomain.com/static/1234567890abcdef.mp3"
}
Enter fullscreen mode Exit fullscreen mode

Open that URL in a browser – you should hear the spoken sentence.


4. Hooking the Service into WordPress

4.1 Add a Simple Shortcode

Add the following snippet to your theme’s functions.php (or a custom plugin). It creates a [ai_narrate] shortcode that takes the post content, sends it to your Flask service, and renders an HTML5 audio player.

function ai_narrate_shortcode( $atts, $content = null ) {
    // Grab the current post content if no explicit text is passed
    if ( is_null( $content ) ) {
        $content = get_the_content();
    }

    // Prepare the request to our Flask TTS endpoint
    $tts_endpoint = 'https://voice.yourdomain.com/tts';
    $response = wp_remote_post( $tts_endpoint, array(
        'headers' => array( 'Content-Type' => 'application/json' ),
        'body'    => wp_json_encode( array( 'text' => wp_strip_all_tags( $content ) ) ),
        'timeout' => 30,
    ) );

    if ( is_wp_error( $response ) ) {
        return '<p>⚠️ Could not generate narration.</p>';
    }

    $body = wp_remote_retrieve_body( $response );
    $data = json_decode( $body, true );

    if ( empty( $data['audio_url'] ) ) {
        return '<p>⚠️ No audio returned.</p>';
    }

    // Return the audio player markup
    return sprintf(
        '<audio controls preload="none" style="width:100%%; margin-top:1rem;">
            <source src="%s" type="audio/mpeg">
            Your browser does not support the audio element.
         </audio>',
        esc_url( $data['audio_url'] )
    );
}
add_shortcode( 'ai_narrate', 'ai_narrate_shortcode' );
Enter fullscreen mode Exit fullscreen mode

4.2 Use It in a Post

In the Gutenberg editor, simply add a Shortcode block and type:

[ai_narrate]
Enter fullscreen mode Exit fullscreen mode

When the post is rendered, the shortcode calls your Flask service, fetches the MP3, and drops an audio player right under the content. Readers can click “play” to listen to the entire article.


5. Voice Cloning (Optional)

ElevenLabs lets you clone a custom voice with just a few minutes of audio. After uploading a sample in the ElevenLabs dashboard, you’ll receive a new VOICE_ID. Replace the VOICE_ID constant in app.py with that ID to give your blog a unique brand voice.

VOICE_ID = "your_custom_voice_id_here"
Enter fullscreen mode Exit fullscreen mode

Now every narration sounds like you (or your chosen character). This is a powerful way to reinforce brand identity.


6. Deploying with Bluehost – Why It’s a Good Fit

  • One‑Click WordPress – Bluehost’s managed WordPress install gets you up and running in seconds, leaving you free to focus on the AI side.
  • Cheap Python support – Their shared hosting plans include SSH access and the ability to run a lightweight Flask app behind Apache/Nginx.
  • Built‑in SSL – All traffic (including your TTS endpoint) is automatically HTTPS, which ElevenLabs requires for API calls.

If you already have a site on Bluehost, you can spin up the Flask service on the same account without paying extra. For new projects, the Bluehost starter plan is under $5/month and includes a free domain for the first year.


7. Scaling Tips

  • Cache the MP3 URLs – Store the generated audio path in a custom WordPress post meta field so you don’t re‑request TTS on every page load.
  • Use a CDN – Point the static/ folder to Cloudflare or BunnyCDN for faster audio delivery.
  • Rate‑limit your endpoint – Add a simple token bucket in Flask or use a WordPress plugin to prevent abuse.

8. Wrap‑Up

You now have a complete, developer‑friendly pipeline:

  1. ElevenLabs provides high‑quality, natural‑sounding speech (and optional voice cloning).
  2. Flask on a Bluehost server turns text into MP3 files on demand.
  3. A WordPress shortcode fetches the audio and embeds a player for your readers.

Give it a spin, experiment with different voices, and watch your engagement metrics climb.


Call to Action

Ready to bring your blog to life? Sign up for ElevenLabs today and grab your API key, then spin up a cheap, reliable host with Bluehost. In just a few minutes you’ll have AI voice narration powering every post—no extra plugins, no manual uploads. Happy coding!

Top comments (0)