electron: speechSynthesis.getVoices() returns an empty array
Preflight Checklist
- I have read the Contributing Guidelines for this project.
- I agree to follow the Code of Conduct that this project adheres to.
- I have searched the issue tracker for an issue that matches the one I want to file, without success.
Issue Details
-
Electron Version:
- ^8.0.2
-
Operating System:
- Ubuntu 18.04 x64
-
Last Known Working Electron version:
- Not ^4.x.y, I never tried below
Expected Behavior
An array of voices is expectedActual Behavior
speechSynthesis.getVoices() returns an empty array always with or without the internetTo Reproduce
Here fiddle link: https://gist.github.com/cfe130888196196153f5240e30d8e4b5
$ git clone https://github.com/whizyrel/app-bible -b electron-devel
$ npm install
$ electron .
Screenshots

Additional Information
With or without the internet speechSynthesis.getVoices() returns an empty array. In the browser, it returns an array of SpeechSynthesisVoice using chrome when the internet is connected. Further info: https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesis/getVoices
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Comments: 20 (5 by maintainers)
I don’t know if this is the case but this worked for me.
I think the reason that
getVoices()returns an empty array is because they are not there by default. BUT, the following works for me:@LoLei You are right. List of voices are returned after manually reloading the page but this does not fit angular at all. So what i did was load from URL the first time and when it resolves, reload manually and load from URL again. Well, it may not be smart, but it looks fair and is not what i want but I would take it. This is a work around for anyone that might have this issue again, thanks @LoLei. I guess this issue can be closed now, if there is no activity in a long time, I would close it.
summarily,
Thanks everyone.
Awesome @LoLei, this works! Thanks! 🙇♀️
@caarmen: In case this helps, I’ve described in a comment above how I use a workaround that doesn’t rely on any framework like Angular:
I use something like this to call
getVoiceson the first page load and then trigger a page reload:@codebytere We found a cumbersome workaround, the underlying issue is still there.
I’m getting the same on Linux Electron 9.0.0.
I have installed
speech-dispatcherandespeak-ng. I am starting Electron withapp.commandLine.appendSwitch('enable-speech-dispatcher').Calling
window.speechSynthesis.getVoices()at any time after first loading the page, returns an empty array.In Firefox, it returns
However, the default voice can still be used in Electron. Which is unfortunately in Afrikaans, since it is the first voice in the list.
So using a voice from within Electron is possible, it uses the default voice, but retrieving a list of voices is not possible, and therefore setting the voice to a new one is not possible either.
It can be tested by using this website: https://mdn.github.io/web-speech-api/speak-easy-synthesis/ With a slight modification to get arround a null reference due to the empty list.
I can confirm though that this also happens in Chromium (83.0.4103.61) (
chromium --enable-speech-dispatcher) itself, although Chromium reports:However, I also found out that if you let Chromium sit for a long while, and try
window.speechSynthesis.getVoices()again, it will load the full array. Or if you reload the page. Sometimes. It does not seem deterministic. As pointed out here, it seem like thespeechSynthesismodule itself is loaded some time after the page is loaded. This is a distinct event from thevoiceschangedevent, which I’ve tried incorporating in Chromium to no avail. In Firefox, it works fine.I can get it working in Electron relatively consistently by starting the Electron app from the command line, then reloading the page manually. Once the initial reload is done, the voices are ready as well.
Another difference between Firefox and Electron/Chromium: In Firefox the voices have their languages set properly in the
langproperty. E.g.And in Chromium the
langproperty is missing and the name contains the local synth software for some reason.So all I can conclude is that something is messed up.
I have looked at https://github.com/electron/electron/issues/586, https://github.com/electron/electron/issues/11585.
EDIT
Turns out it doesn’t solely depend on a reload. The nonworking
window.speechSynthesis.getVoices()also needs to be called once before the reload.So what I ended up doing, in
index.html:window.speechSynthesis.getVoices()// nonworking but necessarywindow.speechSynthesis.getVoices()Of course also with setting a flag to refresh the page only once.
Also reproducible on macOS - i’ll try to take a look soon.
Seems like this has never worked (I tried v4–v9) on macOS, so this isn’t a regression.
https://github.com/electron/electron/pull/14070 seems relevant.