ngx-speech-button
June 4, 2026 ยท View on GitHub
An Angular directive that provides an easy-to-use wrapper for the Web Speech API, enabling voice input functionality with minimal setup.
Add voice recognition to any button with:
- ๐ค Click to listen - Toggle speech recognition on/off
- ๐ Real-time transcripts - Get live updates as the user speaks
- โ Final results - Receive completed transcripts when speech ends
- โ๏ธ Configurable - Customize language, continuous mode, and more
- ๐ง Advanced access - Direct access to the underlying SpeechRecognition instance
Features
- Works on any clickable element (buttons, icons, etc.)
- Real-time transcript streaming
- Configurable speech recognition settings
- Exposes underlying SpeechRecognition API for advanced use cases
- SSR-safe with platform detection
- Standalone directive (no module required)
- Fully typed with TypeScript
- Lightweight with no dependencies
Install
npm i -S ngx-speech-button && npm i -D @types/dom-speech-recognition
Note: The
@types/dom-speech-recognitionpackage provides TypeScript types for the Web Speech API and is required as a dev dependency.
Compatibility
| Angular Version | Package Version |
|---|---|
| 22.x | 0.0.x |
| <=21.x | Last release before Angular 22 support |
Browser Support
The Web Speech API is supported in modern browsers. Check Can I Use for current browser support.
Usage
Basic Usage
Add the ngxSpeechButton directive to any clickable element to enable voice input.
import { Component } from '@angular/core';
import { SpeechButton } from 'ngx-speech-button';
@Component({
selector: 'app-voice-input',
imports: [SpeechButton],
template: `
<button ngxSpeechButton #speech="ngxSpeechButton" (transcriptCompleted)="onTranscript($event)">
{{ speech.listening() ? '๐ด Listening...' : '๐ค' }}
</button>
<p>Transcript: {{ transcript }}</p>
`,
})
export class VoiceInputComponent {
transcript = '';
onTranscript(text: string) {
this.transcript = text;
}
}
Real-time Streaming
Use transcriptChanged to receive updates as the user speaks:
@Component({
selector: 'app-live-transcription',
imports: [SpeechButton],
template: `
<button
ngxSpeechButton
(transcriptChanged)="liveText = $event"
(transcriptCompleted)="finalText = $event"
>
๐ค Speak
</button>
<p>Live: {{ liveText }}</p>
<p>Final: {{ finalText }}</p>
`,
})
export class LiveTranscriptionComponent {
liveText = '';
finalText = '';
}
Custom Configuration
Configure the SpeechRecognition API with the config input:
@Component({
selector: 'app-custom-speech',
imports: [SpeechButton],
template: `
<button
ngxSpeechButton
[config]="{ lang: 'en-US', continuous: false, interimResults: true }"
(transcriptCompleted)="onComplete($event)"
>
๐ค English Only
</button>
`,
})
export class CustomSpeechComponent {
onComplete(text: string) {
console.log('Final:', text);
}
}
Error Handling
Handle speech recognition errors with the error output:
@Component({
selector: 'app-error-handling',
imports: [SpeechButton],
template: `
<button ngxSpeechButton (transcriptCompleted)="onComplete($event)" (error)="onError($event)">
๐ค Speak
</button>
@if (errorMessage) {
<p class="error">{{ errorMessage }}</p>
}
`,
})
export class ErrorHandlingComponent {
errorMessage = '';
onComplete(text: string) {
console.log(text);
}
onError(event: SpeechRecognitionErrorEvent) {
this.errorMessage = `Error: ${event.error}`;
}
}
Advanced: Accessing the Recognition Instance
For advanced use cases, access the underlying SpeechRecognition instance:
@Component({
selector: 'app-advanced',
imports: [SpeechButton],
template: ` <button ngxSpeechButton #speech="ngxSpeechButton">๐ค</button> `,
})
export class AdvancedComponent implements AfterViewInit {
@ViewChild('speech') speechButton!: SpeechButton;
ngAfterViewInit() {
// Attach custom event handlers
this.speechButton.recognition?.addEventListener('soundstart', () => {
console.log('Sound detected');
});
this.speechButton.recognition?.addEventListener('speechstart', () => {
console.log('Speech started');
});
}
}
Conditional Display
Hide the button when the Web Speech API is not available:
<button
ngxSpeechButton
#speech="ngxSpeechButton"
[hidden]="!speech.available()"
(transcriptCompleted)="onComplete($event)"
>
๐ค Voice Input
</button>
@if (!speech.available()) {
<p>Voice input not supported in this browser</p>
}
API Reference
SpeechButton Directive
| Selector | [ngxSpeechButton] |
|---|
| Export As | ngxSpeechButton |
|---|
Inputs
| Name | Type | Default | Description |
|---|---|---|---|
| config | SpeechRecognitionConfig | {} | Configuration options for SpeechRecognition API. |
Outputs
| Name | Type | Description |
|---|---|---|
| transcriptChanged | EventEmitter<string> | Emits the current transcript as it updates. |
| transcriptCompleted | EventEmitter<string> | Emits the final transcript when recognition ends. |
| error | EventEmitter<SpeechRecognitionErrorEvent> | Emits when a speech recognition error occurs. |
Properties
| Name | Type | Description |
|---|---|---|
| available | Signal<boolean> | Whether the Web Speech API is available. |
| listening | Signal<boolean> | Whether speech recognition is currently active. |
| recognition | SpeechRecognition | null | The underlying SpeechRecognition instance for advanced use. |
SpeechRecognitionConfig Type
type SpeechRecognitionConfig = Partial<
Pick<SpeechRecognition, 'lang' | 'continuous' | 'interimResults' | 'maxAlternatives' | 'grammars'>
>;
| Property | Type | Default | Description |
|---|---|---|---|
| lang | string | navigator.language | Language for recognition (e.g., 'en-US'). |
| continuous | boolean | true | Whether to return continuous results. |
| interimResults | boolean | false | Whether to return interim results. |
| maxAlternatives | number | 1 | Maximum number of alternative transcriptions. |
| grammars | SpeechGrammarList | - | Grammar list to constrain recognition. |
Requirements
- Angular 22+
- Browser with Web Speech API support
Development
To clone this repo and run it locally:
git clone https://github.com/JayChase/ngx-speech-button.git
cd ngx-speech-button
npm install
npm run build
Demo
ng serve demo
Run tests
npm test
License
MIT