JS Bits with Bill
JS Bits with Bill

JS Bits with Bill

Creating a Text-To-Speech program in Vanilla JS

Creating a Text-To-Speech program in Vanilla JS

JS Bits with Bill's photo
JS Bits with Bill

Published on Oct 29, 2021

2 min read

If you haven't been too traumatized from using a Microsoft browser, you might have discovered Edge's built-in "Read Aloud" feature which will speak the highlighted text out loud right in your browser:

As of now, Chrome has no such feature so we're going to build it ourselves! Here's the code:

function speak() {
  const text = window.getSelection().toString();
  const utterance = new SpeechSynthesisUtterance(text);
  utterance.voice = getFemaleVoice();
  speechSynthesis.speak(utterance);
}

// Optional - select one of several voices
function getFemaleVoice() {
  const voiceIndex = 4;
  return speechSynthesis.getVoices()[voiceIndex];
}

So essentially we just pass in the string from window.getSelection().toString() to a new instance of SpeechSynthesisUtterance and call the .speak() method and that's it!

But we need a way to trigger our speak() function. You could create a Chrome extension to add this functionality to the context menu but I've chosen to use DevTool's "Snippets" just to keep it simple. Snippets are your own custom saved scripts you can paste into your browser and run at will. They're super handy for utility functions like cookie getter/setters, JS libraries like Lodash or jQuery, custom UI modifications, etc.

Once you create a snippet, you can run the code either by clicking "Run Snippet" or pressing Command/Control + Enter. You can also run them directly from the DevTools Command Menu.

Snippets are located in the Sources tab and then on the sidebar click "Snippets":

We just need a bit more overhead to account for the asynchronous loading of speechSynthesis.getVoices() so that our desired voice has loaded before the speech audio runs. The final code looks like this:

if (voiceLoaded()) {
  speak();
} else {
  speechSynthesis.addEventListener('voiceschanged', speak);
}

function speak() {
  const text = window.getSelection().toString();
  const utterance = new SpeechSynthesisUtterance(text);
  utterance.voice = getFemaleVoice();
  speechSynthesis.speak(utterance);
}

function getFemaleVoice() {
  const voiceIndex = 4;
  return speechSynthesis.getVoices()[voiceIndex];
}

function voiceLoaded() {
  return speechSynthesis.getVoices().length;
}

And now we can do the laundry and have our article read to us at the same time! 🔊


Yo! I post byte-sized tips like these often. Follow me if you crave more! 🍿

I'm on Twitter, TikTok and I have a new debugging course dropping soon!

 
Share this