
Security News
Critical Security Vulnerability in React Server Components
React disclosed a CVSS 10.0 RCE in React Server Components and is advising users to upgrade affected packages and frameworks to patched versions now.
dictate-button
Advanced tools
Customizable Web Component that adds speech-to-text dictation capabilities to text fields
A customizable web component that adds speech-to-text dictation capabilities to any text input, textarea field, or contenteditable element on your website.
Developed for dictate-button.io.
data-dictate-button-on attribute (exclusive mode) or without the data-dictate-button-off attribute (inclusive mode)Choose the auto-inject mode that best suits your needs:
| Mode | Description | Scripts |
|---|---|---|
| Exclusive | Enables for text fields with the data-dictate-button-on attribute only. | inject-exclusive.js |
| Inclusive | Enables for text fields without the data-dictate-button-off attribute. | inject-inclusive.js |
Both auto-inject modes:
document.documentElement.lang (if present). Long codes like en-GB are normalized to en.In your HTML <head> tag, add the following script tag:
<script type="module" crossorigin src="https://cdn.dictate-button.io/inject-exclusive.js"></script>
Add the data-dictate-button-on attribute to any textarea, input[type="text"], input[type="search"], input without a type attribute, or element with the contenteditable attribute:
<textarea data-dictate-button-on></textarea>
<input type="text" data-dictate-button-on />
<input type="search" data-dictate-button-on />
<input data-dictate-button-on />
<div contenteditable data-dictate-button-on />
In your HTML <head> tag, add the following script tag:
<script type="module" crossorigin src="https://cdn.dictate-button.io/inject-inclusive.js"></script>
All textarea, input[type="text"], input[type="search"], input elements without a type attribute, and elements with the contenteditable attribute that lack data-dictate-button-off will be automatically enhanced by default.
To disable that for a specific field, add the data-dictate-button-off attribute to it this way:
<textarea data-dictate-button-off></textarea>
<input type="text" data-dictate-button-off />
<input type="search" data-dictate-button-off />
<input data-dictate-button-off />
<div contenteditable data-dictate-button-off />
Import the component and use it directly in your code:
<script type="module" crossorigin src="https://cdn.dictate-button.io/dictate-button.js"></script>
<dictate-button size="30" api-endpoint="https://api.dictate-button.io/transcribe" language="en"></dictate-button>
Import once for your app:
// For selected text fields (with data-dictate-button-on attribute):
import 'dictate-button/inject-exclusive'
// or for all text fields (except those with data-dictate-button-off attribute):
import 'dictate-button/inject-inclusive'
To choose between exclusive and inclusive auto-inject modes, see the Auto-inject modes section.
If you need more control over when and how the dictate buttons are injected, you can use the library functions directly:
Tip: You can also import from subpaths (e.g., 'dictate-button/libs/injectDictateButton') for smaller bundles, if your bundler resolves package subpath exports.
import 'dictate-button' // Required when using library functions directly
import { injectDictateButton, injectDictateButtonOnLoad } from 'dictate-button/libs'
// Inject dictate buttons immediately to matching elements
injectDictateButton(
'textarea.custom-selector', // CSS selector for target elements
{
buttonSize: 30, // Button size in pixels (optional; default: 30)
verbose: false, // Log events to console (optional; default: false)
customApiEndpoint: 'https://api.example.com/transcribe' // Optional custom API endpoint
}
)
// Inject on DOM load with mutation observer to catch dynamically added elements
injectDictateButtonOnLoad(
'input.custom-selector', // CSS selector for target elements
{
buttonSize: 30, // Button size in pixels (optional; default: 30)
verbose: false, // Log events to console (optional; default: false)
customApiEndpoint: 'https://api.example.com/transcribe', // Optional custom API endpoint
watchDomChanges: true // Watch for DOM changes (optional; default: false)
}
)
Note: the injector mirrors the target field’s display/margins into the wrapper,
sets wrapper width to 100% for block-level fields, and adds padding to avoid the button overlapping text.
The wrapper also has the dictate-button-wrapper class for easy styling.
The dictate-button component emits the following events:
recording:started: Fired when user starts recording.recording:stopped: Fired when user stops recording.recording:failed: Fired when an error occurs during recording.transcribing:started: Fired when transcribing is started.transcribing:finished: Fired when transcribing is complete. The event detail contains the transcribed text.transcribing:failed: Fired when an error occurs during transcribing.The ideal scenario is when user first starts recording (recording:started), then stops recording (recording:stopped), then the recorded audio is sent to the server for processing (transcribing:started), and finally the transcribed text is received (transcribing:finished).
recording:started -> recording:stopped -> transcribing:started -> transcribing:finished
In case of an error in recording or transcribing, the recording:failed or transcribing:failed event is fired, respectively.
Example event handling:
const dictateButton = document.querySelector('dictate-button');
dictateButton.addEventListener('transcribing:finished', (event) => {
const transcribedText = event.detail;
console.log('Transcribed text:', transcribedText);
// Add the text to your input field
document.querySelector('#my-input').value += transcribedText;
});
| Attribute | Type | Default | Description |
|---|---|---|---|
| size | number | 30 | Size of the button in pixels |
| apiEndpoint | string | https://api.dictate-button.io/transcribe | API endpoint for transcription service |
| language | string | (not set) | Optional language code (e.g., 'en', 'fr', 'de') which may speed up the transcription. |
| theme | string | (inherits from page) | 'light' or 'dark' |
| class | string | Custom CSS class |
You can customize the appearance of the dictate button using CSS parts:
/* Style the button container */
dictate-button::part(container) {
/* Custom styles */
}
/* Style the button itself */
dictate-button::part(button) {
/* Custom styles */
}
/* Style the button icons */
dictate-button::part(icon) {
/* Custom styles */
}
By default, dictate-button uses the https://api.dictate-button.io/transcribe endpoint for speech-to-text conversion.
You can specify your own endpoint by setting the apiEndpoint attribute.
The API expects:
audio: Audio data as a File (audio/webm format)origin: The origin of the website (automatically added)language: Optional language code (if provided as an attribute)text property containing the transcribed textThe dictate-button component requires the following browser features:
Works in all modern browsers (Chrome, Firefox, Safari, Edge).
FAQs
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
React disclosed a CVSS 10.0 RCE in React Server Components and is advising users to upgrade affected packages and frameworks to patched versions now.

Research
/Security News
We spotted a wave of auto-generated “elf-*” npm packages published every two minutes from new accounts, with simple malware variants and early takedowns underway.

Security News
TypeScript 6.0 will be the last JavaScript-based major release, as the project shifts to the TypeScript 7 native toolchain with major build speedups.