Question · Dictation in your apps
How do you add speech recognition to a website with JavaScript?
Create a SpeechRecognition object, set its language, read the text in its result event, and call start() from a button click. Check first for the constructor, since some browsers do not have it, and show a message with a typed alternative when it is missing.
Updated October 17, 20263 min read7 cited facts, each traced to its source
Create a SpeechRecognition object, set its language, read the text in its result event, and call start() from a button click. Check first that the constructor exists, because a browser without it will throw an error. The code below does that, and it falls back to a message when recognition is unavailable.
The interface comes from the Web Speech API. The guide to the Web Speech API explains the whole interface, and which browsers support it lists the versions. The code below is a starting point. We did not run it in every browser, so test it in each one you support.
Check for the constructor before you build the button
Chrome and Edge expose the unprefixed name in newer versions, and Chrome's older releases expose the prefixed name. The code tries both, then stops if neither exists:
const Recognition = window.SpeechRecognition || window.webkitSpeechRecognition;
const startButton = document.querySelector('#start');
const output = document.querySelector('#output');
if (!Recognition) {
output.textContent = 'Speech recognition is not available in this browser. Type your text instead.';
startButton.disabled = true;
} else {
const recognition = new Recognition();
recognition.lang = 'en-US';
recognition.interimResults = true;
recognition.continuous = false;
recognition.onresult = (event) => {
const text = Array.from(event.results).map((r) => r [0].transcript).join('');
output.textContent = text;
};
recognition.onerror = (event) => {
output.textContent = `Error: ${event.error}`;
};
startButton.addEventListener('click', () => recognition.start());
}
The unprefixed name works in Chrome from version 139, and the prefixed name from version 33 1. Trying both keeps the page working on older releases. A missing constructor should produce a plain message, not an empty button.
Start recognition only after the visitor clicks
The specification says that browsers "must only start speech input sessions with explicit, informed user consent" 2. That is why the code calls start() inside a click handler, and not when the page loads.
The first start also brings up the browser's permission prompt. In Chrome on a computer, the visitor chooses Allow, Allow this time or Never allow 3. Your page should handle a refusal, because the error arrives in the error event and the page should explain what to change.
Set continuous only for long dictation
By default, continuous is false, which means each recognition returns a single result 4. For a short command, that is fine. For long dictation, set it to true, and read results from event.resultIndex onward so you do not repeat text you already have:
let finalText = '';
recognition.continuous = true;
recognition.onresult = (event) => {
let interim = '';
for (let i = event.resultIndex; i < event.results.length; i++) {
const result = event.results [i];
if (result.isFinal) {
finalText += result [0].transcript;
} else {
interim += result [0].transcript;
}
}
output.textContent = finalText + interim;
};
The code sets interimResults explicitly, so the page does not depend on the browser's default for it.
Handle the errors that visitors will hit
Two errors cover most real problems. A missing network connection produces a network error, because the recognition needs one 5. Blocked speech input produces a not-allowed error, which the browser sends when it blocks input for security, privacy or user preference reasons 6.
In both cases, show a message and leave a text box available. Do not let the page wait for a result that will never come.
It depends: the browser may send the audio to a server
By default in Chrome, recognition runs through a server-based engine. Audio is sent to a web service, so the feature does not work offline 7. If your page handles sensitive speech, read whether the Web Speech API sends audio to Google before you decide where it runs.
What to do
- Check for the constructor, and try both names. Show a message with a typed alternative when neither exists.
- Start from a click, and set the language yourself. Do not start on page load.
- Set
continuousto true for long dictation, and read results fromresultIndex. - Handle the network and not-allowed errors. Show a clear message for each.
- Test offline and with the microphone blocked, in every browser you support, including Safari with Siri turned off.
The glossary entry for the Web Speech API explains the names used here. For a broader view of dictation in apps, see our overview of dictation. If the page needs to transcribe audio files rather than live speech, free audio to text in the browser is an option that needs no code.
Evidence
Every number on this page, with where it comes from. Open a fact to see the exact words in its source.
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
Go deeper
Related questions
- Can Whisper run in the browser?
- Does the Web Speech API send audio to Google?
- Which browsers support speech recognition?
- Can Chrome do speech to text offline?
- Can Google Docs transcribe an audio file?
- Can Microsoft Word transcribe an audio file?
- Can OneNote transcribe audio?
- Can you control Linux with voice commands?
Referenced by
- Voice Typing in Google Docs, Word and Every Other AppTopic
- Speech Recognition: What It Is and How Well It WorksTopic
- Web Speech API: Speech Recognition in the BrowserGuide
- How do you add speech recognition to a React or React Native app?Question
- How do you add speech recognition to a Unity or Unreal game?Question
- Which browsers support speech recognition?Question
- Why does speech recognition show a network or not-allowed error?Question