Best practices
Following these recommendations will help you build a reliable and maintainable Dictation SDK integration.
Always call CustomizeComponents before Login
INVOX.CustomizeComponents() must be invoked before any call to INVOX.Login() or invoxBar.login(). If the order is reversed, the SDK fires a NOT_CUSTOMIZED_COMPONENTS event and none of the registered callbacks will be bound.
// Correct order
INVOX.CustomizeComponents(function () {
INVOX.OnRunningRecognizer(function () { /* ... */ });
INVOX.OnPausedRecognizer(function () { /* ... */ });
});
invoxBar.login(credentials, connectionConfig);
Always register the NOT_CUSTOMIZED_COMPONENTS event as a safety net during development:
document.addEventListener(INVOX.eventTypeReport.NOT_CUSTOMIZED_COMPONENTS, function (e) {
console.error('CustomizeComponents was not called before Login:', e.detail);
});
Handle all login events
Registering only LOGIN_SUCCESS is not sufficient for production. Always handle LOGIN_ERROR and NOT_CUSTOMIZED_COMPONENTS so that connection problems are surfaced clearly to both developers and end users.
document.addEventListener(INVOX.eventTypeReport.LOGIN_SUCCESS, function () {
// Set writer target and enable UI
});
document.addEventListener(INVOX.eventTypeReport.LOGIN_ERROR, function (e) {
// Inform the user of the failure and disable dictation-related UI
console.error('Connection failed:', e.detail);
});
document.addEventListener(INVOX.eventTypeReport.NOT_CUSTOMIZED_COMPONENTS, function (e) {
console.error('Initialization error:', e.detail);
});
document.addEventListener(INVOX.eventTypeReport.LOGGING_OUT, function () {
// Clean up writer state and disable dictation controls
});
Implement a local-to-remote connection fallback
When your users may have the Invox Medical Local Dictation Agent installed on their machine, attempt a local connection first and fall back to the Remote Dictation Service only if it fails. This reduces latency for users who are running the agent.
async function connectWithFallback(credentials) {
const localConfig = { port: 8443, useDictationService: false };
const remoteConfig = { host: 'your-host.invoxmedical.com', port: 8443, useDictationService: true };
try {
await invoxBar.login(credentials, localConfig);
console.log('Connected via local agent');
} catch {
try {
await invoxBar.login(credentials, remoteConfig);
console.log('Connected via remote service');
} catch (e) {
console.error('All connection attempts failed:', e);
}
}
}
The local connection attempt will time out after 13 seconds by default before rejecting. You can reduce this with the localTimeoutAttempt option (in milliseconds):
const localConfig = { port: 8443, useDictationService: false, localTimeoutAttempt: 5000 };
Always handle microphone permission events
Browsers gate microphone access behind a user permission prompt. Your application must respond gracefully to both grant and deny outcomes.
INVOX.CustomizeComponents(function () {
INVOX.OnGrantedAudioSource(function () {
const micName = INVOX.GetMicrophoneName();
console.log('Microphone ready:', micName);
// Enable dictation controls in your UI
});
INVOX.OnDeniedAudioSource(function () {
INVOX.SetDictationPaused();
// Show a message asking the user to grant microphone access
console.warn('Microphone access was denied by the user');
});
});
Lock writer target switching during active dictation
When the page contains multiple editable fields, prevent the active writer target from changing while dictation is running. Switching targets mid-sentence results in split or lost text.
function setActiveEditor(id) {
const session = INVOX.GetCurrentSession();
const isDictating = session && session.State === INVOX.SessionStateEnum.RECOGNIZING;
if (isDictating) return;
INVOX.SetTextWriter(INVOX.TextAreaTextWriter);
INVOX.SetWriterTarget(document.getElementById(id));
}
Attach this guard to the onfocus event of each editable element (see Example 2 for a full implementation).
Customize the INVOX Bar appearance to match your brand
The INVOX Bar exposes CSS custom properties that let you align its appearance with your application's design system. Override these in your stylesheet:
:root {
--invox-bar-color__primary: #1a73e8; /* primary background */
--invox-bar-color__microphone: #e53935; /* microphone button */
--invox-bar-color__vumeter-bars--active: #00c853; /* VUMeter active bars */
--invox-bar-font__color: #ffffff; /* label text */
--invox-bar-font__size: 0.85rem;
--invox-bar-size__height: 36px;
--invox-dialogs-size__width: 460px;
--invox-dialogs-size__height: 460px;
}
A full list of available variables is documented inside libs/integrations/invox-bar/invox-bar-component.css.
Log SDK events during development
The SDK includes a built-in logger. Increasing the log level during development helps diagnose connection and recognition issues:
// Available levels: TRACE, DEBUG, INFO, WARN, ERROR, FATAL
INVOX.ChangeLogLevel('DEBUG');
Remember to reset the log level (or disable extended logging) before deploying to production.