Electrobun Webview Tag
<electrobun-webview> embeds a separate native BrowserView and keeps its
position synchronized with an element in the host page. It behaves like an
isolated iframe, but the embedded content is rendered by its own native
webview rather than inside the host document.
Import electrobun/view once in the host page. That module registers the
custom element and augments TypeScript’s DOM types.
<electrobun-webview id="documentation" src="https://example.com" sandbox style="display: block; width: 100%; height: 480px"></electrobun-webview>import type { WebviewTagElement } from "electrobun/view";import "electrobun/view";
const webview = document.querySelector("electrobun-webview");if (!webview) throw new Error("The embedded webview was not found");
webview.on("dom-ready", () => { console.log("Embedded content is ready", webview.webviewId);});
webview.loadURL("https://example.com/docs");
const typedWebview: WebviewTagElement = webview;void typedWebview;Attributes
| Attribute | Value | Purpose |
|---|---|---|
src | URL | Initial URL. Changing it navigates the webview. |
html | HTML string | Initial inline document. Changing it loads the new HTML. |
preload | JavaScript string | Code evaluated before the embedded page’s scripts. |
partition | string | Persistent session/storage partition name. |
renderer | native or cef | Renderer for this webview. Defaults to native. |
sandbox | boolean attribute | Disables Electrobun RPC in the child while retaining events and navigation controls. |
transparent | boolean attribute | Starts the native layer transparent. |
passthrough | boolean attribute | Starts with pointer input passing through to the host page. |
spellcheck | boolean attribute | Enables native WKWebView spell checking where supported. |
masks | comma-separated selectors | Cuts holes in the native layer for matching host elements. |
navigation-rules | JSON string array | Initial native navigation allow/block rules. |
Boolean attributes are enabled by their presence. For spellcheck, an
explicit value of "false" is also treated as disabled.
<electrobun-webview src="https://example.com" renderer="cef" partition="account-a" sandbox transparent passthrough masks=".toolbar, .popover" navigation-rules='["^*", "https://example.com/*"]'></electrobun-webview>Set creation-only attributes such as renderer, partition, and sandbox
before attaching the element to the document. Use the methods below for
runtime changes.
Navigation
import "electrobun/view";
const webview = document.querySelector("electrobun-webview");if (!webview) throw new Error("The embedded webview was not found");
webview.loadURL("https://example.com");webview.loadHTML("<!doctype html><title>Inline document</title><h1>Hello</h1>");webview.reload();webview.goBack();webview.goForward();
const [canGoBack, canGoForward] = await Promise.all([ webview.canGoBack(), webview.canGoForward(),]);console.log({ canGoBack, canGoForward });setNavigationRules(rules) applies rules in native code. * is a wildcard,
^ marks a blocking rule, and the last matching rule wins. With no matching
rule, navigation is allowed.
import "electrobun/view";
const webview = document.querySelector("electrobun-webview");if (!webview) throw new Error("The embedded webview was not found");
webview.setNavigationRules([ "^*", "https://example.com/*", "https://cdn.example.com/*",]);An empty rules array restores the default allow behavior.
Visibility And Input
The toggle methods accept an explicit state. Omit it to invert the current state.
import "electrobun/view";
const webview = document.querySelector("electrobun-webview");if (!webview) throw new Error("The embedded webview was not found");
webview.toggleTransparent(true);webview.togglePassthrough(true);webview.toggleHidden(false);webview.syncDimensions(true);
console.log({ transparent: webview.transparent, passthrough: webview.passthroughEnabled, hidden: webview.hidden,});syncDimensions(true) forces an immediate geometry and mask update. Normal
layout changes are synchronized automatically.
Mask Selectors
The native webview is a separate layer above the host page, so ordinary
z-index cannot place host DOM over it. A mask selector cuts rectangular
holes in the native layer. Matching host elements then remain visible and
receive input.
<div class="toolbar">Host controls</div><electrobun-webview src="https://example.com" sandbox masks=".toolbar, .context-menu"></electrobun-webview>import "electrobun/view";
const webview = document.querySelector("electrobun-webview");if (!webview) throw new Error("The embedded webview was not found");
webview.addMaskSelector(".autocomplete");webview.removeMaskSelector(".autocomplete");console.log([...webview.maskSelectors]);Each selector can match any number of elements. Invalid selectors are ignored. Masks use bounding rectangles; rounded corners and partial alpha do not alter the rectangular cutout.
On Linux, passthrough and mask punch-through are unavailable for embedded
views inside transparent BrowserWindows. Use a non-transparent parent for
those overlays. On Windows, WebView2 does not honor these overlay operations;
set bundleCEF: true and use the CEF renderer when masks or passthrough are
required.
Spell Check
import "electrobun/view";
const webview = document.querySelector("electrobun-webview");if (!webview) throw new Error("The embedded webview was not found");
const supported = await webview.setSpellCheck(true);console.log({ supported, enabled: webview.spellCheckEnabled });The promise resolves to true only when the current renderer supports the
change. Native WKWebView on macOS is currently supported; other renderers
return false without changing renderer state.
Find And Developer Tools
import "electrobun/view";
const webview = document.querySelector("electrobun-webview");if (!webview) throw new Error("The embedded webview was not found");
webview.findInPage("Electrobun", { forward: true, matchCase: false });webview.stopFindInPage();
webview.openDevTools();webview.closeDevTools();webview.toggleDevTools();
webview.executeJavascript("document.documentElement.dataset.embedded = 'true'");Events
Use on and off for custom-element events. A listener receives a
CustomEvent; payload shape depends on the native event.
import "electrobun/view";
const webview = document.querySelector("electrobun-webview");if (!webview) throw new Error("The embedded webview was not found");
const onNavigation = (event: CustomEvent) => { console.log("Navigation payload", event.detail);};
webview.on("did-navigate", onNavigation);webview.off("did-navigate", onNavigation);Supported event names are:
will-navigatedid-navigatedid-navigate-in-pagedid-commit-navigationdom-readyhost-messagenew-window-opendownload-starteddownload-progressdownload-completeddownload-failedload-startedload-committedload-finished
Embedded content can emit a host-message from its preload script:
window.__electrobunSendToHost({ type: "ready", documentTitle: document.title });The host receives that value in the event detail. This event bridge remains available in sandbox mode; Electrobun RPC does not.
Properties
| Property | Type | Notes |
|---|---|---|
webviewId | number | null | Native view ID after initialization. |
src | string | null | Attribute-backed URL. |
html | string | null | Attribute-backed inline HTML. |
preload | string | null | Attribute-backed preload source. |
renderer | "native" | "cef" | Attribute-backed renderer. |
sandbox | boolean | Read-only initialized sandbox state. |
transparent | boolean | Current transparency state. |
passthroughEnabled | boolean | Current input passthrough state. |
spellCheckEnabled | boolean | Requested spell-check state. |
hidden | boolean | Current native visibility state. |
maskSelectors | Set<string> | Active host-page mask selectors. |
The element also inherits standard HTMLElement properties such as id,
style, and dataset.