Using the Web Speech API - Web APIs | MDN
https://developer.mozilla.org/en-US/docs/Web/API/Web_Speech_API/Using_the_Web_Speech_API • 182 KB fetched
Open original page
Using the Web Speech API - Web APIs | MDN
*
Skip to main content
*
Skip to search
HTML
HTML: Markup language
HTML reference
*
Elements
*
Global attributes
*
Attributes
*
See all…
HTML guides
*
Responsive images
*
HTML cheatsheet
*
Date & time formats
*
See all…
Markup languages
*
SVG
*
MathML
*
XML
CSS
CSS: Styling language
CSS reference
*
Properties
*
Selectors
*
At-rules
*
Values
*
See all…
CSS guides
*
Box model
*
Animations
*
Flexbox
*
Colors
*
See all…
Layout cookbook
*
Column layouts
*
Centering an element
*
Card component
*
See all…
JavaScript JS
JavaScript: Scripting language
JS reference
*
Standard built-in objects
*
Expressions & operators
*
Statements & declarations
*
Functions
*
See all…
JS guides
*
Control flow & error handing
*
Loops and iteration
*
Working with objects
*
Using classes
*
See all…
Web APIs
Web APIs: Programming interfaces
Web API reference
*
File system API
*
Fetch API
*
Geolocation API
*
HTML DOM API
*
Push API
*
Service worker API
*
See all…
Web API guides
*
Using the Web animation API
*
Using the Fetch API
*
Working with the History API
*
Using the Web speech API
*
Using web workers
All
All web technology
Technologies
*
Accessibility
*
HTTP
*
URI
*
Web extensions
*
WebAssembly
*
WebDriver
*
See all…
Topics
*
Media
*
Performance
*
Privacy
*
Security
*
Progressive web apps
Learn
Learn web development
Frontend developer course
*
Getting started modules
*
Core modules
*
MDN Curriculum
*
Check out the video course from Scrimba, our partner
Learn HTML
*
Structuring content with HTML module
Learn CSS
*
CSS styling basics module
*
CSS layout module
Learn JavaScript
*
Dynamic scripting with JavaScript module
Tools
Discover our tools
*
Playground
*
HTTP Observatory
*
Border-image generator
*
Border-radius generator
*
Box-shadow generator
*
Color format converter
*
Color mixer
*
Shape generator
About
Get to know MDN better
*
About MDN
*
Advertise with us
*
Community
*
MDN on GitHub
Blog
Toggle sidebar
*
Web
*
Web APIs
*
Web Speech API
*
Using the Web Speech API
Theme
*
OS default
*
Light
*
Dark
English (US)
Remember language
Learn more
*
Deutsch
*
English (US)
*
Español
*
Français
*
日本語
*
Русский
*
中文 (简体)
Using the Web Speech API
The Web Speech API provides two distinct areas of functionality — speech recognition and speech synthesis (also known as text to speech, or TTS) — which open up interesting possibilities for accessibility and control. This article provides an introduction to both the areas, along with demos.
In this article
*
Speech recognition
*
On-device speech recognition
*
Contextual biasing in speech recognition
*
Speech synthesis
Speech recognition
Speech recognition involves receiving audio from a device's microphone (or from an audio track), which is then checked by a speech recognition service. When the service successfully recognizes a word or phrase, it returns a text string (or a list of strings) that you can use to initiate further actions.
The Web Speech API has a main controller interface for this — SpeechRecognition — and several related interfaces for representing results.
Generally, the speech recognition system available on the user's device is used for the speech recognition. Most modern operating systems have a speech recognition system for issuing voice commands, such as Dictation on macOS or Copilot on Windows.
By default, using speech recognition on a web page involves a server-based recognition engine. Your audio is sent to a web service for recognition processing, so it won't work offline.
To improve privacy and performance, you can specify that speech recognition be performed on the device. This ensures that neither the audio nor the transcribed speech are sent to a third-party service for processing. We cover the on-device functionality in more detail in the On-device speech recognition section.
Demo
To demonstrate how to use speech recognition, we've created a sample app called Speech color changer . After you press the Start recognition button, say an HTML color keyword. The app's background color will change to that color.
To run the demo, navigate to the live demo URL in a supporting browser .
HTML and CSS
The HTML and CSS for the app are basic. There's a title, an instruction paragraph ( <p> ), a control <button> , and an output paragraph where we display diagnostic messages, including the words that our app recognized.
html
<h1>Speech color changer</h1>
<p class="hints"></p>
<button>Start recognition</button>
<p class="output"><em>...diagnostic messages</em></p>
The CSS provides a basic responsive styling so that it looks OK across devices.
JavaScript
Let's look at the JavaScript in a bit more detail.
Prefixed properties
Some browsers currently support speech recognition with prefixed properties.
Therefore, at the start of our code, we include these lines to allow for both prefixed properties and unprefixed versions:
js
const SpeechRecognition =
window.SpeechRecognition || window.webkitSpeechRecognition;
const SpeechRecognitionEvent =
window.SpeechRecognitionEvent || window.webkitSpeechRecognitionEvent;
Color list
The next part of our code defines a few sample colors that we print to the UI to give users an idea of what to say:
js
const colors = [
"aqua",
"azure",
"beige",
"bisque",
"black",
"blue",
"brown",
"chocolate",
"coral",
// …
];
Creating a speech recognition instance
Next, we define a speech recognition instance to control the recognition in our app. We do this by using the SpeechRecognition() constructor.
js
const recognition = new SpeechRecognition();
We then set a few properties of the recognition instance:
* SpeechRecognition.continuous : Controls whether results are captured continuously ( true ) or only once each time a recognition starts ( false ).
* SpeechRecognition.lang : Sets the language of the recognition. Setting this explicitly is the recommended best practice.
* SpeechRecognition.interimResults : Defines whether the speech recognition system should return interim results or only final results. For this demo, final results are good enough.
* SpeechRecognition.maxAlternatives : Sets the number of alternative potential matches that should be returned per result. This can sometimes be useful, say if a result is not completely clear and you want to display a list of alternatives for the user to choose from. But it's not needed for this demo, so we're just specifying one (which is the default anyway).
js
recognition.continuous = false;
recognition.lang = "en-US";
recognition.interimResults = false;
recognition.maxAlternatives = 1;
Starting the speech recognition
After grabbing references to the output paragraph, the <html> element, the instruction paragraph, and the <button> , we implement an onclick handler. When a user presses the button, the speech recognition service starts by calling SpeechRecognition.start() . We've also used a forEach() method to output colored indicators showing what colors users can try to say.
js
const diagnostic = document.querySelector(".output");
const bg = document.querySelector("html");
const hints = document.querySelector(".hints");
const startBtn = document.querySelector("button");
const colorHTML = colors
.map((v) => `<span style="background-color:${v};">${v}</span>`)
.join("");
hints.innerHTML = `Press the button then say a color to change the background color of the app. Try ${colorHTML}.`;
startBtn.onclick = () => {
recognition.start();
console.log("Ready to receive a color command.");
};
Receiving and handling results
Once the speech recognition has started, several event handlers become available, which you can use to retrieve results and other related information (see Events for SpeechRecognition ). The most common one is the result event, which fires after a successful result is received:
js
recognition.onresult = (event) => {
const color = event.results[0][0].transcript;
diagnostic.textContent = `Result received: ${color}.`;
bg.style.backgroundColor = color;
console.log(`Confidence: ${event.results[0][0].confidence}`);
};
The second line is a bit complex, so we'll explain each part here:
* The SpeechRecognitionEvent.results property returns a SpeechRecognitionResultList object containing SpeechRecognitionResult objects. It has a getter so it can be accessed like an array — the first [0] returns the SpeechRecognitionResult at position 0 .
* Each SpeechRecognitionResult object in turn contains SpeechRecognitionAlternative objects, each representing an individual recognized word. These also have getters, so they can be accessed like arrays — the second [0] returns the SpeechRecognitionAlternative at position 0 .
* The transcript property of the SpeechRecognitionAlternative returns a string containing the recognized text. This value is then used to set the background color to a recognized color and also report it as a diagnostic message in the UI.
We also use the speechend event to stop the speech recognition service (using SpeechRecognition.stop() ) after a single word has been recognized:
js
recognition.onspeechend = () => {
recognition.stop();
};
Handling errors and unrecognized speech
The last two handlers cover cases where the spoken term isn't recognized or an error occurs with the recognition. The nomatch event is supposed to handle the first case, although in most cases the recognition engine will return something, even if it is unintelligible:
js
recognition.onnomatch = (event) => {
diagnostic.textContent = "I didn't recognize that color.";
};
The error event handles cases when there is an actual error with the recognition — the SpeechRecognitionErrorEvent.error property contains the error returned:
js
recognition.onerror = (event) => {
diagnostic.textContent = `Error occurred in recognition: ${event.error}`;
};
On-device speech recognition
Speech recognition is usually performed using an online service. This means that an audio recording is sent to a server for processing, and the results are then returned to the browser. This has a couple of problems:
* Privacy: Many users are not comfortable with their speech being sent to a server.
* Performance: Sending data to a server for every bit of recognition can slow down performance in more intensive applications, and your apps won't work offline.
To mitigate these problems, the Web Speech API lets you specify that speech recognition should be handled on-device by the browser. This requires a one-time language pack download for each language you want to recognize; once installed, the functionality will be available offline.
This section explains how to use on-device speech recognition.
Demo
To demonstrate on-device speech recognition, we've created a sample app called On-device speech color changer ( run the demo live ).
This demo works in a very similar fashion to the online speech color changer demo discussed earlier, with the differences noted below.
Note:
In the original speech color changer demo, we included extra lines to handle browsers that support the Web Speech API only with vendor-prefixed properties (see the Prefixed properties section for more details). In the on-device version of the demo, prefix-handling code is not needed because the implementations that support this functionality do so without prefixes.
Specifying on-device recognition
To specify that you want to use the browser's on-device processing, set the SpeechRecognition.processLocally property to true before starting any speech recognition (the default value is false ):
js
recognition.processLocally = true;
Checking availability and installing language packs
For on-device speech recognition to work, the browser must have a language pack installed for the language you want to recognize. If you run the start() method after specifying processLocally = true but the correct language pack isn't installed, the function call will fail with a language-not-supported error.
To get the correct language pack installed, ensure you follow these two steps:
* Check whether the language pack is available on the user's device: This is handled using the SpeechRecognition.available() static method.
* Install the language pack if it isn't available: This is handled using the SpeechRecognition.install() static method.
These steps are handled in the following click event handler on the app's control <button> :
js
startBtn.addEventListener("click", () => {
// check availability of target language
SpeechRecognition.available({ langs: ["en-US"], processLocally: true }).then(
(result) => {
if (result === "unavailable") {
diagnostic.textContent = `en-US is not available to download at this time. Sorry!`;
} else if (result === "available") {
recognition.start();
console.log("Ready to receive a color command.");
} else {
diagnostic.textContent = `en-US language pack is downloading...`;
SpeechRecognition.install({
langs: ["en-US"],
processLocally: true,
}).then((result) => {
if (result) {
diagnostic.textContent = `en-US language pack downloaded. Start recognition again.`;
} else {
diagnostic.textContent = `en-US language pack failed to download. Try again later.`;
}
});
}
},
);
});
The available() method takes an options object containing two properties:
* A langs array containing the languages to check availability for.
* A processLocally boolean specifying whether to check for the availability of the language only on-device ( true ) or either locally or via a server-based recognition service ( false , the default).
When run, this method returns a Promise that resolves with an enumerated value indicating the availability of the specified languages. In our demo, we test for three conditions:
* If the resulting value is unavailable , it means that no suitable language pack is available to download. We also print an appropriate message to the output.
* If the resulting value is available , it means that the language pack is available locally, so recognition can begin. In this case, we run start() and log a message to the console when the app is ready to receive speech.
* If the value is something else ( downloadable or downloading ), we print a diagnostic message to inform the user that a language pack download is starting, then run the install() method to handle the download.
The install() method works in a similar way to the available() method, except that its options object only takes the langs array. When run, it starts downloading all the language packs for the languages indicated in langs and returns a Promise that resolves with a boolean indicating whether the specified language packs were downloaded and installed successfully ( true ) or not ( false ).
For this demo, we print a diagnostic message to indicate the success and failure cases. In a more complete app, you'd probably disable the controls during the download process and enable them again after the promise resolves.
Permissions-policy integration
The use of the available() and install() methods is controlled by the on-device-speech-recognition Permissions-Policy . Specifically, where a defined policy blocks usage, any attempts to call these methods will fail.
The default allowlist value for on-device-speech-recognition is self . This means you don't need to worry about adjusting the policy unless you're attempting to use these methods in embedded cross-origin documents or want to explicitly disable their use.
Specifying quality level requirements
The available() and install() methods both support the quality option. This allows you to check support for varying speech recognition complexity levels — for example, processing short voice commands is much simpler than handling dictation/transcription, and the former use case is likely to be supported by more hardware and language pack combinations than the latter.
For example, the following code snippet is a modification of code from the On-device speech color changer example in which we call the available() method with the quality option set to dictation , to check whether on-device recognition will support this quality level. If the result returned is unavailable , we set the SpeechRecognition object's processLocally property to false to force the API to use a cloud recognition service, then start() the recognition service.
If the result is available , we are good to go, so we just call start() to start on-device recognition. If the result is any other value, we run the install() method with the quality option set to dictation to install the required language packs.
js
startBtn.addEventListener("click", () => {
// Check availability of on-device target language dictation quality
SpeechRecognition.available({
langs: ["en-US"],
processLocally: true,
quality: "dictation",
}).then((result) => {
if (result === "unavailable") {
diagnostic.textContent = `On-device recognition for dictation not available, running with cloud recognition`;
recognition.processLocally = false;
recognition.start();
} else if (result === "available") {
recognition.start();
console.log("Ready to receive a color command.");
} else {
diagnostic.textContent = `en-US language pack downloading`;
SpeechRecognition.install({
langs: ["en-US"],
processLocally: true,
quality: "dictation",
}).then((result) => {
if (result) {
diagnostic.textContent = `en-US language pack downloaded. Try again.`;
} else {
diagnostic.textContent = `en-US language pack failed to download. Try again later.`;
}
});
}
});
});
Contextual biasing in speech recognition
There will be times when a speech recognition service will fail to correctly recognize a specific word or phrase. This most often happens with domain-specific terms (such as medical or scientific vocabulary), proper nouns, uncommon phrases, or words that sound similar to other words and so may be misidentified.
For example, during testing, we found that our On-device speech color changer had trou
Links found on this page
- Skip to main content [direct]
- HTML: Markup language [direct]
- Elements [direct]
- Global attributes [direct]
- Attributes [direct]
- See all… [direct]
- Responsive images [direct]
- HTML cheatsheet [direct]
- Date & time formats [direct]
- See all… [direct]
- SVG [direct]
- MathML [direct]
- XML [direct]
- CSS: Styling language [direct]
- Properties [direct]
- Selectors [direct]
- At-rules [direct]
- Values [direct]
- See all… [direct]
- Box model [direct]
- Animations [direct]
- Flexbox [direct]
- Colors [direct]
- See all… [direct]
- Column layouts [direct]
- Centering an element [direct]
- Card component [direct]
- See all… [direct]
- JavaScript: Scripting language [direct]
- Standard built-in objects [direct]
- Expressions & operators [direct]
- Statements & declarations [direct]
- Functions [direct]
- See all… [direct]
- Control flow & error handing [direct]
- Loops and iteration [direct]
- Working with objects [direct]
- Using classes [direct]
- See all… [direct]
- Web APIs: Programming interfaces [direct]
- File system API [direct]
- Fetch API [direct]
- Geolocation API [direct]
- HTML DOM API [direct]
- Push API [direct]
- Service worker API [direct]
- Using the Web animation API [direct]
- Using the Fetch API [direct]
- Working with the History API [direct]
- Using web workers [direct]
- All web technology [direct]
- Accessibility [direct]
- HTTP [direct]
- URI [direct]
- Web extensions [direct]
- WebAssembly [direct]
- WebDriver [direct]
- Media [direct]
- Performance [direct]
- Privacy [direct]
- Security [direct]
- Progressive web apps [direct]
- Learn web development [direct]
- Getting started modules [direct]
- Core modules [direct]
- MDN Curriculum [direct]
- Check out the video course from Scrimba, our partner [direct]
- Structuring content with HTML module [direct]
- CSS styling basics module [direct]
- CSS layout module [direct]
- Dynamic scripting with JavaScript module [direct]
- Playground [direct]
- HTTP Observatory [direct]
- Border-image generator [direct]
- Border-radius generator [direct]
- Box-shadow generator [direct]
- Color format converter [direct]
- Color mixer [direct]
- Shape generator [direct]
- About MDN [direct]