> ## Documentation Index
> Fetch the complete documentation index at: https://webview.js.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Webview — Embedded Browser View Control API

> Control the embedded browser view: load URLs or HTML, run scripts, handle IPC, manage cookies, use DevTools, and expose Node.js functions to the page.

`Webview` controls the embedded browser view attached to a [`BrowserWindow`](/api/browser-window). You create a `Webview` by calling `win.createWebview(options)` on an existing window. Each window can host one or more webviews, and a webview can display any URL, inline HTML, or content served by a [custom protocol](/guides/custom-protocols).

```ts theme={null}
const webview = win.createWebview({ url: 'https://example.com' });
```

Hold a strong JavaScript reference to each `Webview` for its intended lifetime. The root `Application` owns the native view and disposes it during `app.exit()`, but you need the wrapper object to call methods and listen to events.

***

## Creation Options

Pass a `WebviewOptions` object to `win.createWebview()`.

| Option              | Type                       | Description                                                                                               |
| ------------------- | -------------------------- | --------------------------------------------------------------------------------------------------------- |
| `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 (**child webviews only**)                                                   |
| `y`                 | `number`                   | Top offset in logical pixels (**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`, positions the webview at the specified bounds within the parent window                       |
| `enableDevtools`    | `boolean`                  | Enable the browser DevTools panel                                                                         |
| `transparent`       | `boolean`                  | Render the webview with a transparent background                                                          |
| `incognito`         | `boolean`                  | Private/incognito mode — no cookies or storage are persisted                                              |
| `userAgent`         | `string`                   | Override the browser's `User-Agent` header                                                                |
| `preload`           | `string`                   | JavaScript string injected into every page before any page script runs                                    |
| `ipcName`           | `string`                   | Alias for the IPC global (e.g. `'bindings'` exposes `window.bindings`). `window.ipc` is always available. |
| `webContext`        | `WebContext`               | Shared [WebContext](/api/web-context) for cookie, cache, and storage isolation                            |
| `navigationHandler` | `(url: string) => boolean` | Synchronous guard called before every navigation. Return `false` to cancel.                               |

<Note>
  For **top-level** webviews (not child), omit `x`, `y`, `width`, and `height`. Doing so lets the webview fill the window and resize with it automatically. Setting explicit bounds fixes the size, which causes a black-border artifact when the window is maximized.
</Note>

***

## Navigation

Load new content or refresh the current page at any time:

```ts theme={null}
webview.loadUrl(url: string): void
webview.loadHtml(html: string): void
webview.loadUrlWithHeaders(url: string, headers: HeaderData[]): void
webview.reload(): void
webview.url(): string | null   // currently displayed URL, or null
```

`HeaderData` shape:

```ts theme={null}
interface HeaderData {
  key: string;
  value?: string;
}
```

### Navigation handler

When you provide `navigationHandler` in the creation options, WebviewJS calls it synchronously before every navigation attempt. Return `true` to allow navigation or `false` to block it.

```ts theme={null}
const webview = win.createWebview({
  url: 'https://example.com',
  navigationHandler: (url) => {
    // Block any navigation away from example.com
    return new URL(url).hostname === 'example.com';
  },
});
```

<Warning>
  Keep `navigationHandler` fast and **do not return a Promise**. The handler runs synchronously on the browser thread. A `navigation` event is always emitted regardless of whether navigation is allowed or cancelled.
</Warning>

***

## Script Execution

Run JavaScript in the page context:

```ts theme={null}
// Fire-and-forget — no return value
webview.evaluateScript(script: string): void

// Run a script and receive the stringified result in an error-first callback
webview.evaluateScriptWithCallback(
  script: string,
  callback: (err: Error | null, result: string) => void
): void
```

```ts theme={null}
// Fire-and-forget example
webview.evaluateScript(`document.title = 'Updated by Node'`);

// Read back a value
webview.evaluateScriptWithCallback(
  `JSON.stringify({ title: document.title, url: location.href })`,
  (err, result) => {
    if (err) throw err;
    const data = JSON.parse(result);
    console.log('Page info:', data);
  }
);
```

***

## Webview Events

`Webview` extends Node.js `EventEmitter`. Use `.on()`, `.once()`, `.off()`, `.addListener()`, `.removeListener()`, and `.removeAllListeners()` to manage listeners.

### Event reference

| Event                | Payload fields   | Description                                                                                       |
| -------------------- | ---------------- | ------------------------------------------------------------------------------------------------- |
| `page-load-started`  | `url`            | The browser started loading a new page                                                            |
| `page-load-finished` | `url`            | The page finished loading                                                                         |
| `title-changed`      | `title`          | The `<title>` element changed                                                                     |
| `download-started`   | `url`            | A file download started                                                                           |
| `download-completed` | `url`, `success` | A file download completed. `success` is `true` on success                                         |
| `navigation`         | `url`            | Fired for every navigation attempt, whether allowed or cancelled by `navigationHandler`           |
| `new-window`         | `url`            | The page called `window.open()` or used `target="_blank"`. The request is allowed after dispatch. |

<Note>
  Download events are observational — you cannot cancel a download from these events.
  On Windows, `new-window` is dispatched from a separate WebView2 thread and is therefore observational only.
</Note>

### Usage example

```ts theme={null}
webview.on('page-load-started', ({ url }) => {
  console.log('Loading:', url);
});

webview.on('page-load-finished', ({ url }) => {
  console.log('Finished:', url);
});

webview.on('title-changed', ({ title }) => {
  win.setTitle(title ?? 'My App');
});

webview.on('download-started', ({ url }) => {
  console.log('Downloading:', url);
});

webview.on('download-completed', ({ url, success }) => {
  console.log(url, success ? 'downloaded OK' : 'FAILED');
});

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

webview.on('new-window', ({ url }) => {
  console.log('Page wants to open:', url);
});
```

***

## IPC

The page sends a message to Node by calling `window.ipc.postMessage(body)`. Register a handler in Node with:

```ts theme={null}
webview.onIpcMessage(handler: (message: IpcMessage) => void): void
```

`IpcMessage` shape:

```ts theme={null}
interface IpcMessage {
  body: Buffer;           // raw message body bytes
  method: string;         // HTTP-style method string
  headers: HeaderData[];  // optional headers
  uri: string;            // request URI
}
```

```ts theme={null}
webview.onIpcMessage((message) => {
  const text = message.body.toString('utf8');
  console.log('IPC message:', text);
});
```

Set `ipcName: 'bindings'` in `WebviewOptions` to also expose `window.bindings` as an alias for `window.ipc`. The default `window.ipc` global is always available.

See the [IPC Messaging guide](/guides/ipc-messaging) for a complete walkthrough.

***

## expose()

`expose()` is a higher-level IPC helper that makes Node.js values and functions available as a named global in the page. Every exposed function becomes a `Promise`-returning stub in the browser, even if the Node.js implementation is synchronous.

```ts theme={null}
webview.expose(name: string, target: ExposedTarget): void
```

```ts theme={null}
type ExposedTarget = Record<
  string,
  JsonValue | ((...args: any[]) => unknown | Promise<unknown>)
>;
```

### Example

```ts theme={null}
import { readFile } from 'node:fs/promises';

webview.expose('native', {
  appVersion: '1.0.0',            // static JSON value
  isDarkMode: true,

  readFile: async (path: string) => {
    return readFile(path, 'utf8');
  },

  writeLog: (message: string) => {
    console.log('[page]', message);
  },
});
```

In the page:

```js theme={null}
// Static values are available synchronously
console.log(window.native.appVersion);  // "1.0.0"

// Functions always return Promises
const content = await window.native.readFile('/etc/hostname');
await window.native.writeLog('Page loaded');
```

### Rules and limitations

* Only **enumerable own data properties** of `target` are exposed. Getters, setters, and inherited properties are ignored.
* Static values and function arguments/results must be **JSON-serializable**. Cyclic structures, `BigInt`, functions as values, and `undefined` results throw a `SerializationError`.
* The namespace `name` must be a **valid JavaScript identifier** and can only be exposed **once per webview**.

See the [IPC guide](/guides/ipc-messaging) for more detail and the runnable expose example.

***

## Cookie Management

Read and write the webview's cookie store:

```ts theme={null}
// Get all cookies, or cookies for a specific URL
webview.getCookies(url?: string): WebviewCookie[]

// Set a cookie
webview.setCookie(cookie: WebviewCookie): void

// Delete a cookie by name, optionally scoped to a domain and path
webview.deleteCookie(name: string, domain?: string, path?: string): void

// Erase all cookies, cache, local storage, and IndexedDB data
webview.clearAllBrowsingData(): void
```

`WebviewCookie` shape:

```ts theme={null}
interface WebviewCookie {
  name: string;
  value: string;
  domain?: string;
  path?: string;
  httpOnly?: boolean;
  secure?: boolean;
  sameSite?: 'strict' | 'lax' | 'none';
}
```

```ts theme={null}
// Set a session cookie
webview.setCookie({
  name: 'session',
  value: 'abc123',
  domain: 'example.com',
  path: '/',
  httpOnly: true,
  secure: true,
  sameSite: 'strict',
});

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

// Remove a specific cookie
webview.deleteCookie('session', 'example.com', '/');
```

***

## DevTools

Open, close, or check the browser developer tools:

```ts theme={null}
webview.openDevtools(): void
webview.closeDevtools(): void
webview.isDevtoolsOpen(): boolean
```

<Note>
  DevTools must be enabled at creation time via `enableDevtools: true` in `WebviewOptions`.
</Note>

***

## Appearance

Set the background color shown before (or behind) page content. Each component is an integer in the range **0–255**:

```ts theme={null}
webview.setBackgroundColor(r: number, g: number, b: number, a: number): void
```

```ts theme={null}
// White background
webview.setBackgroundColor(255, 255, 255, 255);

// Fully transparent
webview.setBackgroundColor(0, 0, 0, 0);
```

***

## Focus

Control which element holds keyboard input:

```ts theme={null}
webview.focus(): void        // give keyboard focus to the webview content area
webview.focusParent(): void  // return focus to the parent BrowserWindow
```

***

## Bounds (Child Webviews)

For child webviews you can reposition or resize the view at runtime without recreating it.

<Note>
  Bounds methods are only meaningful for **child webviews** created with `child: true`. On top-level webviews the bounds track the window size automatically.
</Note>

```ts theme={null}
webview.getBounds(): WebviewBounds | null
webview.setBounds(bounds: WebviewBounds): void

// Convenience read-only properties (logical pixels)
webview.width: number | null
webview.height: number | null
webview.x: number | null
webview.y: number | null
```

```ts theme={null}
interface WebviewBounds {
  x: number;
  y: number;
  width: number;
  height: number;
}
```

```ts theme={null}
// Move and resize a child webview
webview.setBounds({ x: 10, y: 60, width: 800, height: 500 });

const bounds = webview.getBounds();
console.log(bounds); // { x: 10, y: 60, width: 800, height: 500 }
```

***

## Disposal

Call `webview.dispose()` to release a webview before `app.exit()`:

```ts theme={null}
webview.dispose(): void
webview.isDisposed(): boolean
```

You can also use the `using` declaration for automatic cleanup:

```ts theme={null}
{
  using webview = win.createWebview({ url: 'https://example.com' });
  // ... use the webview ...
} // webview.dispose() called automatically
```

Disposal is **idempotent** — calling it more than once is safe. `app.exit()` also disposes every webview created under that application. Disposing the parent `BrowserWindow` also disposes all its webviews.
