Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/webviewjs/webview/llms.txt

Use this file to discover all available pages before exploring further.

Webview is the embedded browser surface attached to a BrowserWindow. You create it by calling win.createWebview() after the application is ready. Once created, a webview gives you full control over page navigation, JavaScript execution, two-way IPC messaging, cookie management, DevTools access, and layout positioning. The native webview lifetime is owned by the root Application — keep a JavaScript reference to the Webview wrapper for as long as you need to interact with it.
Never discard the Webview reference returned by win.createWebview(). The native resource stays alive via the Application, but dropping the wrapper loses access to all methods and EventEmitter listeners.

Creation Options

Pass these to win.createWebview(options):
interface WebviewOptions {
  url?: string;
  html?: string;
  x?: number;
  y?: number;
  width?: number;
  height?: number;
  child?: boolean;
  enableDevtools?: boolean;
  transparent?: boolean;
  incognito?: boolean;
  userAgent?: string;
  preload?: string;
  ipcName?: string;
  webContext?: WebContext;
  navigationHandler?: (url: string) => boolean;
  theme?: Theme;
  hotkeysZoom?: boolean;
  clipboard?: boolean;
  autoplay?: boolean;
  backForwardNavigationGestures?: boolean;
}
url
string
URL to load when the webview is created. Mutually exclusive with html.
html
string
Inline HTML string to render. Mutually exclusive with url.
x
number
Left offset in logical pixels from the window’s top-left corner. Child webviews only.
y
number
Top offset in logical pixels from the window’s top-left corner. Child webviews only.
width
number
Width in logical pixels. Child webviews only.
height
number
Height in logical pixels. Child webviews only.
child
boolean
When true, the webview is positioned relative to the parent window using x/y/width/height instead of filling the full window area.
enableDevtools
boolean
Enable the built-in DevTools panel.
transparent
boolean
Make the webview background transparent. The window must also be transparent.
incognito
boolean
Private/incognito mode — no cookies, cache, or storage are persisted between sessions.
userAgent
string
Override the browser’s User-Agent header string.
preload
string
JavaScript source string injected into every page before any page scripts run. Use for setting up globals, polyfills, or IPC bridges.
ipcName
string
Custom name for the IPC global (default: "ipc", i.e. window.ipc). Pass "bindings" to expose window.bindings as an alias alongside the default window.ipc.
webContext
WebContext
A WebContext created via app.createWebContext(). Webviews sharing the same context share cookies, cache, local storage, and IndexedDB. See WebContext reference.
navigationHandler
(url: string) => boolean
Synchronous navigation guard called before every navigation. Return true to allow, false to cancel. Keep this callback fast — do not return a Promise. A navigation event is always emitted regardless of the handler’s return value.
theme
Theme
Override the preferred color scheme. Theme.Light (0), Theme.Dark (1), or Theme.System (2).
hotkeysZoom
boolean
Allow pinch-to-zoom and keyboard zoom shortcuts inside the webview.
clipboard
boolean
Enable clipboard access from page JavaScript.
autoplay
boolean
Allow media autoplay without user interaction.
backForwardNavigationGestures
boolean
Enable swipe-back / swipe-forward navigation gestures (macOS and iOS).
For top-level webviews, omit x/y/width/height so the view automatically fills the window and resizes with it. Setting explicit bounds on a top-level webview causes a black-border artifact when the window is maximised.

loadUrl(url)

webview.loadUrl(url: string): void
Navigate to the given URL.

loadHtml(html)

webview.loadHtml(html: string): void
Replace the current page content with the provided HTML string.

loadUrlWithHeaders(url, headers)

webview.loadUrlWithHeaders(url: string, headers: HeaderData[]): void
url
string
required
URL to navigate to.
headers
HeaderData[]
required
Additional HTTP request headers as { key: string, value?: string }[].

reload()

webview.reload(): void
Reload the current page.

url()

webview.url(): string | null
Returns the URL currently displayed in the webview, or null if no page is loaded.
const webview = win.createWebview({
  html: `
    <a href="https://example.com">Allowed</a>
    <a href="https://blocked.example">Blocked</a>
  `,
  navigationHandler(url) {
    const allowed = !url.startsWith('https://blocked.example');
    console.log(allowed ? 'allow' : 'block', url);
    return allowed;
  },
});

webview.on('navigation', ({ url }) => {
  console.log('Navigation attempted:', url);
});

Script Execution

evaluateScript(js)

webview.evaluateScript(js: string): void
Inject and execute a JavaScript string in the page context. Fire-and-forget — no return value is captured.

evaluateScriptWithCallback(js, callback)

webview.evaluateScriptWithCallback(
  js: string,
  callback: (err: Error | null, result: string) => void
): void
Execute js and receive the serialised result (or an error) in callback. The result is always a string — parse JSON if your script returns a structured value.
webview.evaluateScriptWithCallback(
  'JSON.stringify({ title: document.title, url: location.href })',
  (err, result) => {
    if (err) throw err;
    console.log(JSON.parse(result));
  }
);

preload option

JavaScript provided via the preload option is injected into every page before any of the page’s own scripts execute. Use it to define globals, mock APIs, or establish IPC channels:
const webview = win.createWebview({
  url: 'https://example.com',
  preload: `
    window.__appVersion = '1.2.3';
    window.sendToHost = (msg) => window.ipc.postMessage(msg);
  `,
});

IPC Messaging

onIpcMessage(handler)

Register a handler for messages sent from the page via window.ipc.postMessage(body).
webview.onIpcMessage(handler: (message: IpcMessage) => void): void
handler
function
required
Called with an IpcMessage object for each message from the page.
interface IpcMessage {
  body: Buffer;    // raw message body bytes
  method: string; // HTTP method (usually "POST")
  headers: Array<{ key: string; value?: string }>;
  uri: string;    // request URI
}
webview.onIpcMessage(({ body }) => {
  const text = body.toString('utf8');
  console.log('IPC message from page:', text);
});
Inside the page:
window.ipc.postMessage('Hello from the page!');

expose(name, target)

Expose static JSON values and async Node.js functions under a named global in the page. Page-side functions always return Promises, even if the Node.js implementation is synchronous.
webview.expose(name: string, target: ExposedTarget): void
name
string
required
Valid JavaScript identifier used as the property name on window. Can only be exposed once per webview.
target
ExposedTarget
required
A plain object whose own enumerable properties are either JSON-serialisable values or async functions. Getters, setters, and non-enumerable properties are ignored.
All arguments, static values, and function return values must be JSON-serialisable. Cyclic structures, BigInt, functions-as-values, and undefined results throw a SerializationError.
import { readFile } from 'node:fs/promises';

webview.expose('native', {
  appVersion: '1.0.0',
  isDarkMode: true,
  readFile: async (path) => readFile(path, 'utf8'),
});
In the page:
console.log(window.native.appVersion); // '1.0.0'
const text = await window.native.readFile('/tmp/hello.txt');

Cookies & Storage

getCookies(url?)

webview.getCookies(url?: string): WebviewCookie[]
Return all stored cookies, or only those matching url when provided.
webview.setCookie(cookie: WebviewCookie): void
Store a cookie in the webview’s session.

deleteCookie(name, domain?, path?)

webview.deleteCookie(name: string, domain?: string, path?: string): void
Delete a cookie by name. Provide domain and/or path to narrow the match; omit them to delete across all domains and paths.

clearAllBrowsingData()

webview.clearAllBrowsingData(): void
Erase all cookies, cache entries, local storage, and IndexedDB data for this webview’s session.
// Set a cookie, read it back, then clear everything.
webview.setCookie({
  name: 'session',
  value: 'abc123',
  domain: 'example.com',
  secure: true,
  httpOnly: true,
});

const cookies = webview.getCookies('https://example.com');
console.log(cookies);

webview.clearAllBrowsingData();

DevTools

webview.openDevtools(): void
webview.closeDevtools(): void
webview.isDevtoolsOpen(): boolean
DevTools must be enabled at creation time via enableDevtools: true in WebviewOptions. Calling openDevtools() on a webview created without this option has no effect.

Layout & Bounds

For top-level webviews (the default), the view fills the window automatically and resizes with it — do not call setBounds. For child webviews (child: true), you control the position and size explicitly.

getBounds()

webview.getBounds(): WebviewBounds | null
WebviewBounds
object
{ x: number, y: number, width: number, height: number } — all in logical pixels relative to the window’s top-left corner.

setBounds(bounds)

webview.setBounds(bounds: WebviewBounds): void
Reposition or resize the webview within its window. Values are in logical pixels.

Dimension getters (logical pixels)

webview.width: number | null
webview.height: number | null
webview.x: number | null       // offset from window top-left
webview.y: number | null       // offset from window top-left
null is returned when the property is not applicable (e.g. top-level webview without explicit bounds).

setWebviewVisibility(visible)

webview.setWebviewVisibility(visible: boolean): void
Show or hide the webview without destroying it.

Focus

webview.focus(): void         // give keyboard focus to the webview content area
webview.focusParent(): void   // return focus to the parent window

Appearance

setBackgroundColor(r, g, b, a)

webview.setBackgroundColor(r: number, g: number, b: number, a: number): void
Set the background colour displayed before or behind page content. All channels are 0–255.

zoom(scaleFactor)

webview.zoom(scaleFactor: number): void
Apply a page-level zoom. 1.0 is 100%; 1.5 is 150%.

print()

webview.print(): void
Trigger the system print dialog for the current page.

Events

Webview implements the standard Node.js EventEmitter interface — on, once, off, addListener, removeListener, and removeAllListeners are all available.
EventPayloadDescription
page-load-started{ event, url? }Navigation has committed and the page has begun loading
page-load-finished{ event, url? }Page has fully loaded (including subresources)
title-changed{ event, title? }The document <title> changed
download-started{ event, url? }A file download has begun
download-completed{ event, url?, success? }A download finished (success: true) or failed (success: false)
navigation{ event, url? }A navigation was attempted (fired even if cancelled by navigationHandler)
new-window{ event, url? }Page requested a new window via window.open or target="_blank"
Download events are observational — they do not provide a mechanism to cancel downloads. The new-window event is also observational on Windows, where Wry dispatches it from a separate WebView2 thread.
import { Application } from '@webviewjs/webview';

const app = new Application();
const win = app.createBrowserWindow({ title: 'Webview events', width: 900, height: 600 });

const webview = win.createWebview({
  html: `
    <a href="https://example.com">Navigate</a>
    <a href="https://example.com" target="_blank">New window</a>
  `,
  navigationHandler(url) {
    // Block navigations away from our inline HTML.
    return url.startsWith('about:') || url.startsWith('data:');
  },
});

webview.on('page-load-started', ({ url }) => console.log('Loading:', url));
webview.on('page-load-finished', ({ url }) => console.log('Loaded:', url));
webview.on('title-changed', ({ title }) => console.log('Title:', title));
webview.on('navigation', ({ url }) => console.log('Navigation attempted:', url));
webview.on('new-window', ({ url }) => console.log('New window requested:', url));
webview.on('download-started', ({ url }) => console.log('Download started:', url));
webview.on('download-completed', ({ url, success }) =>
  console.log(`Download ${success ? 'succeeded' : 'failed'}:`, url)
);

app.on('application-close-requested', () => app.exit());
app.run();

Custom Protocols

Custom protocol handlers are registered on the BrowserWindow, not the Webview, and must be registered before calling createWebview():
win.registerProtocol('app', async (request) => {
  const path = new URL(request.url).pathname;
  const body = await readFile(`./dist${path}`);
  return new Response(body, {
    headers: { 'Content-Type': 'text/html' },
  });
});

const webview = win.createWebview({ url: 'app://localhost/index.html' });
See Custom Protocols guide for full details.

Disposal

webview.dispose(): void
webview.isDisposed(): boolean
webview[Symbol.dispose](): void
Call webview.dispose() for early cleanup. Disposal is idempotent — calling it twice is safe. webview.isDisposed() reports the current state. Disposing the parent BrowserWindow or calling app.exit() also disposes every webview automatically.
{
  using webview = win.createWebview({ url: 'https://example.com' });
  // … interact with the webview …
} // webview.dispose() is called automatically

Build docs developers (and LLMs) love