Skip to main content

Webview messaging

Extensions with a webview panel (a dashboard, custom UI, etc.) communicate with their frontend content through message passing. The extension posts messages to the webview, and the webview can post messages back.

Creating a webview panel​

Use extensionApi.window.createWebviewPanel() to create a panel that hosts your frontend, then set its HTML content:

import * as extensionApi from '@podman-desktop/api';

const panel = extensionApi.window.createWebviewPanel('my-extension-view', 'My Extension');
panel.webview.html = getHtml(); // your bundled frontend HTML

extensionContext.subscriptions.push(panel);

Sending messages to the webview​

Call panel.webview.postMessage() with a JSON-serializable payload. This is commonly used from a command handler to tell the frontend to navigate or update its state:

const viewContainerCommand = extensionApi.commands.registerCommand(
'my-extension.viewContainerUsage',
async (container: { id?: string; Id?: string }) => {
const containerId = container?.id ?? container?.Id;
panel.reveal();
await new Promise(resolve => setTimeout(resolve, 200));
await panel.webview.postMessage({
type: 'navigate',
url: `/container/${containerId}`,
});
},
);
extensionContext.subscriptions.push(viewContainerCommand);

NOTE: If the panel was just revealed, the webview may not be mounted yet. A short delay (as above) or a "ready" handshake from the frontend avoids the message being missed.

Receiving messages on the frontend​

Inside the webview content, add a message event listener on window to react to messages posted by the extension:

<script lang="ts">
let status = $state('idle');

window.addEventListener('message', (event: MessageEvent) => {
if (event.data?.type === 'navigate') {
router.goto(event.data.url);
}
});
</script>

Receiving messages from the webview​

The extension can also listen for messages sent from the frontend using panel.webview.onDidReceiveMessage:

panel.webview.onDidReceiveMessage((message: unknown) => {
console.log('Received message from webview', message);
});

The frontend posts messages back with acquirePodmanDesktopApi().postMessage(), which is exposed to the webview content and internally uses the same postMessage mechanism.

Verification​

  1. Build and load your extension, and open its dashboard panel.
  2. Trigger a command that calls panel.webview.postMessage().
  3. Check that the frontend reacts to the message (for example, by navigating to a different page).