
Introduction to Developing Voxtop Extensions
Overview
Voxtop Extensions can be developed using HTML, JavaScript, TypeScript and CSS. Voxtop is an Electron app meaning it can run Chrome compatible web pages.
To create an extension, all you need to do is develop a web application and have it running on a URL that is accessible to your Voxtop users. That URL is the entrypoint for your extension and is what you give to Voxtop when installaing your extension.
Extensions can be as sophisticated as you want. Extensions can be given an icon on the main Voxtop navigation bar providing one click access to any site you wish. At a basic level you might just want to provide a dedicated link to your internal documentation to your team members that have Voxtop. More sophisticated extensions can be developed that interact with Voxtop using functions and even react to what is happening in Voxtop using events.
Extensions run completely isolated from each other and the main Voxtop app. However, for the various areas of the Voxtop app, we have created an isolated set functions and events that you can use in your extensions to create feature rich mini apps that extend the functionality of Voxtop. This has been acheived using the Electron contextBridge feature.
Functions and Events are spefici to and relate to the area of the app that they provide access to. For example for the phone, there are functions to let you place, answer and hangup calls. You can also listen to events such as when calls a received and when the user interacts with the phone in the main Voxtop dialler for dial, answer and hangup.
Getting Started with Development
You do not need to be a developer to add a basic link extension to Voxtop. If you are looking to develop an extensions then you will need some knowledge of HTML, CSS and a scripting language like JavaScript or TypeScript. In this geting strated section, you will need some understanding of HTML, CSS and JavaScript.
The Voxtop API is exposed by the host application on the browser window object. Your extension does not call a remote HTTP endpoint directly to access this API. Instead, it communicates with the Voxotp App through JavaScript functions made available on window.voxtopAPI.
An overview of the lifecycle of an installed extension:
- Voxtop runs your extension, either on startup or when it is launched by the user.
- Your extension should listen for start up events and then begin any code execution.
- Check whether
window.voxtopAPIexists. - Check whether the sub API you want to access is available. For example,
window.voxtopAPI.extension. - If your extension is using events. Subscribe to any events. For example,
window.i164API.extension.onEvent(callback). - The events callback function you provide should validate, unwrap and consume any messages. Displaying the results using HTML.
- Buttons and links in your extension can execute JavaScript and call functions to control Voxtop.
- Your extensions should listen for shutdown events for when the Voxtop user closes or hides your app, or for when Voxtop iteslf closes.
For the remainder of this document, you will be shown examples of how do the following.
- Connect to the extension API
- Run an extension API function
- Suscribe and consume extension events.
The Extension API - window.voxtopAPI.extension
The extension API provides access to functions and events that relate directly to your extension.
Connecting to the Extension API
The extension API is available at:
window.i164API.extension
Extension API - Functions
| Functions | Purpose |
|---|---|
| getInfo() | Provides installation information about your extension |
Function: voxtopAPI.extension.getInfo()
Provides information related to the installed extensions.
| Response | Purpose |
|---|---|
| extensionId | The id of your installed extension |
| installationId | The unique id of this installed extension |
| title | The title of your extension |
| url | The url for your extension |
| visible | The current visibility of the extension |
Example Usage
const info = await window.voxtopAPI.extension.getInfo()
Example Response
{
extensionId: 'voxtop-examples.i164.ai:speechToText',
installationId: '97bbf3c6-d326-418f-86a5-deb79226ddc8',
title: 'i164 Speech-to-Text Demo Extension',
url: 'https://voxtop-examples.i164.ai/speechToText.html?t=1782997002459',
visible: false
}
Extension API - Events
Subscribing
As with all of the voxtopAPI events you subscribe using the onEvent function and pass a callback function to process messages.
const unsubscribeExtensionEvents = window.i164API.extension.onEvent(callback)
Unsubscribing
To unsubscribe from receiving events, simply run the function return from the onEvent function call.
unsubscribeExtensionEvents();
Example Usage
const processMessages = (event) => {
console.log('Received extension event:', event)
}
const unsubscribeExtensionEvents = window.voxtopAPI.extension.onEvent(processMessages)
Extension Event Details
The following extention events a fired by the window.voxtopAPI.extension endpoint.
| Event Type | Details |
|---|---|
| extension.window-show | When the extension window is made visible. |
| extension.window-hide | When the extention window is hidden. |
extension.window-hide
Emitted when the extension window is hidden or closed from view.
{
"eventId": "22a7e86b-69a6-4a4e-8e1a-effb6a1e531d",
"createdAt": "2026-07-03T10:15:30.237Z",
"eventType": "extension.window-hide",
"installationId": "bdfba214-2280-4de1-ae43-2d176f026957"
}
Properties
| Property | Type | Required | Description |
|---|---|---|---|
eventId |
string | Yes | Unique identifier for this event message. |
createdAt |
string | Yes | Time the event occurred, formatted as an ISO 8601 UTC timestamp. |
eventType |
string | Yes | Name of the event. extensions.window-hide or extensions.window-hide. |
installationId |
string | Yes | Unique identifier for the extension installation that generated the event. |
Single Page Extensions
If you are building an extension from scratch, you should design it as a single page JavaScript or TypeScript app. This is essential for maintaining a consistent and unbroken connection to the voxtopAPI, especially for when you are working with Events.
Single page apps do not need to re-subscribe to events when a user transitions from one page to another. In multi-page apps, there will be gaps during reconnection where you may miss event messages from Voxtop.
Vue, React, Angular, Svelte, and even plain Vite + TypeScript make good choices for Single Page App enviroments to help you develop an extension as a single page app.
The Extension Lifecycle
Voxtop manages your extension as a BrowserWindow object. Using the window and document events enables you to detect when your extension is opened and closed.
You can listen for your extension opening and closing using these events.
document.addEventListener('DOMContentLoaded', () => {
console.log('[extension] DOMContentLoaded');
});
window.addEventListener('load', () => {
console.log('[extension] load');
});
window.addEventListener('beforeunload', () => {
console.log('[extension] beforeunload');
});
window.addEventListener('unload', () => {
console.log('[extension] unload');
});
Voxtop controls the visibility of your app dependent on the runtime configuration of your app. See the extension config documentation for more details.
If your extension is a background extension then this will not be visible to the user but your extension will still receive window and browser open and close events.
If you extension is configured with alwaysRunning: true then when the user closes your extension’s window Voxtop will hide your extension rather than close it. When Voxtop itself is closed your extension will be closed.
document.addEventListener('visibilitychange', () => {
console.log(
'[extension] visibilitychange:',
document.visibilityState
);
});
Development Good Practice
Checking whether the API is available
In case this extension is accessed from outside the Voxtop App runtime environment you should check that the API exists. This is also useful if you wish to have your page running eleswhere and wish to only activate additional functionality if the page is running inside Voxtop.
Use a small helper function to check whether the voxtopAPI is present:
function hasExtension() {
return Boolean(
window.voxtopAPI &&
window.voxtopAPI.extension &&
typeof window.i164API.extension.onEvent === 'function'
)
}
This protects your page from errors if it is opened outside the host environment, during local development, or before the host has injected the API.
Subscribing and Unsubscribing to Events
Depending on your extension and particularly if you have a multi-page extensions you must take into account that any subscriptions for event will be cleared when you transition to a new page.
You should always unsubscribe to events although we do automatically clean up any subscriptions that remain if you have not done so to ensure stability of the main Voxtop App.