> ## 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.

# Notification API — Desktop Notifications for Node.js

> Show native desktop notifications from your Node.js desktop app. Supports action buttons, images, persistence, and a browser-compatible EventEmitter API.

The `Notification` class provides a browser-compatible API for native desktop notifications, backed by [notify-rust](https://docs.rs/notify-rust/latest/notify_rust/). You can create and listen to notifications using the same patterns you would in a browser service worker — but running entirely in your Node.js process.

<Info>
  The WebviewJS `Notification` API is intentionally API-compatible with the [Web Notifications API](https://developer.mozilla.org/en-US/docs/Web/API/Notification). Existing code targeting the browser `Notification` constructor works with minimal changes.
</Info>

```js theme={null}
import { Notification } from '@webviewjs/webview';
```

***

## Basic usage

The simplest notification requires only a title:

```js theme={null}
import { Notification } from '@webviewjs/webview';

const notification = new Notification('Build complete', {
  body: 'The release binary is ready.',
});

notification.on('show',  ()            => console.log('Notification shown'));
notification.on('click', ()            => console.log('User clicked it'));
notification.on('close', ()            => console.log('Notification dismissed'));
notification.on('error', ({ error })   => console.error('Failed:', error));
```

***

## Constructor

```ts theme={null}
new Notification(title: string, options?: NotificationOptions)
```

| Parameter | Type                  | Description                                 |
| --------- | --------------------- | ------------------------------------------- |
| `title`   | `string`              | The bold heading shown on the notification. |
| `options` | `NotificationOptions` | Optional configuration (see below).         |

The notification is dispatched to the native backend immediately on construction. There is no separate `.show()` call.

***

## NotificationOptions

```ts theme={null}
interface NotificationOptions {
  body?:               string;
  icon?:               string;
  image?:              string | Buffer;
  badge?:              string;
  tag?:                string;
  data?:               unknown;
  dir?:                'auto' | 'ltr' | 'rtl';
  lang?:               string;
  renotify?:           boolean;
  requireInteraction?: boolean;
  persistent?:         boolean;
  actions?:            NotificationAction[];
  silent?:             boolean;
  timestamp?:          number;
  vibrate?:            number | number[];
}
```

| Field                | Type                       | Mapped to backend | Description                                                                                                                                                                                   |
| -------------------- | -------------------------- | :---------------: | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `body`               | `string`                   |         ✓         | The main message text shown below the title.                                                                                                                                                  |
| `icon`               | `string`                   |         ✓         | Platform icon name (e.g. `'dialog-information'` on Linux) or file path to an image. See [Icon and image](#icon-and-image).                                                                    |
| `image`              | `string \| Buffer`         |         ✓         | A larger inline image. Accepts a local file path string or a `Buffer` of encoded image bytes. See [Icon and image](#icon-and-image).                                                          |
| `requireInteraction` | `boolean`                  |         ✓         | When `true`, the notification stays on screen until the user explicitly acts on it.                                                                                                           |
| `actions`            | `NotificationAction[]`     |         ✓         | Action buttons shown on the notification. Requires `persistent: true`; otherwise the constructor throws a `TypeError`. See [Persistent notifications](#persistent-notifications-and-actions). |
| `persistent`         | `boolean`                  |         ✓         | Keep the Node.js process alive until the notification is interacted with or dismissed. Required when using `actions`.                                                                         |
| `badge`              | `string`                   |         —         | Retained as a readonly instance property for API compatibility; not passed to the native backend.                                                                                             |
| `tag`                | `string`                   |         —         | Retained for API compatibility.                                                                                                                                                               |
| `data`               | `unknown`                  |         —         | Arbitrary data you can attach and read back from the instance.                                                                                                                                |
| `dir`                | `'auto' \| 'ltr' \| 'rtl'` |         —         | Text direction. Retained for API compatibility.                                                                                                                                               |
| `lang`               | `string`                   |         —         | Language tag. Retained for API compatibility.                                                                                                                                                 |
| `renotify`           | `boolean`                  |         —         | Retained for API compatibility.                                                                                                                                                               |
| `silent`             | `boolean`                  |         —         | Retained for API compatibility.                                                                                                                                                               |
| `timestamp`          | `number`                   |         —         | Unix timestamp. Retained for API compatibility.                                                                                                                                               |
| `vibrate`            | `number \| number[]`       |         —         | Vibration pattern. Retained for API compatibility.                                                                                                                                            |

***

## Icon and image

### `icon`

The `icon` field accepts either a **platform icon name** or a **file path**:

* **Platform icon name** — on Linux you can pass a freedesktop.org icon name such as `'dialog-information'` or `'mail-unread'`. The notification server resolves it from the current icon theme.
* **File path** — an absolute or relative path to an image file on disk.

### `image`

The `image` field displays a larger inline image and accepts either a **file path string** or a **`Buffer`** of encoded image bytes. Loading from a `Buffer` is convenient when you already have the image in memory:

```js theme={null}
import { readFile } from 'node:fs/promises';
import { Notification } from '@webviewjs/webview';

const imageData = await readFile('./assets/preview.png');

const notification = new Notification('Screenshot captured', {
  body: 'Click to view',
  image: imageData,   // Buffer containing PNG bytes
});
```

**Supported image formats when using a Buffer:** PNG, JPEG, WebP, GIF, BMP, ICO, TIFF, and other common raster formats.

If the `Buffer` contains invalid or unrecognisable image data, the notification emits an `error` event instead of `show` and is not displayed.

**Platform delivery:**

* **Linux** — decoded pixel data is sent directly to the notification server over D-Bus.
* **Windows / macOS** — WebviewJS writes a temporary PNG file (because the native backends require a file path) and removes it when the notification lifecycle ends.

Remote URL strings are **not** fetched automatically. If your image is hosted remotely, download it into a `Buffer` first using `fetch()` or the `node:https` module, then pass the buffer.

***

## Persistent notifications and actions

By default, notifications are **non-persistent**: their native callbacks do not keep the Node.js process alive. Set `persistent: true` when the notification must remain interactive after the rest of your application has finished running.

```js theme={null}
const notification = new Notification('Download complete', {
  body: 'Your archive is ready to open.',
  persistent: true,
  actions: [
    { action: 'open',    title: 'Open' },
    { action: 'dismiss', title: 'Dismiss' },
  ],
});

notification.on('click', ({ action }) => {
  if (action === 'open')    openArchive();
  if (action === 'dismiss') notification.close();
  // action === '' means the body of the notification was clicked (default activation)
});
```

```ts theme={null}
interface NotificationAction {
  action: string;   // identifier passed back in the click event
  title:  string;   // button label shown on the notification
  icon?:  string;   // icon name/path — retained but not forwarded to the native backend
}
```

**Rules:**

* A non-empty `actions` array requires `persistent: true`. Passing actions without `persistent: true` throws a `TypeError`.
* A default click (body tap, no button) emits `action: ""` in the click event payload.
* Clicking a named action emits `action: "<your-action-identifier>"`.

Because WebviewJS has no service worker to restart, a persistent notification holds the Node.js event loop open until the native backend reports an interaction or closure. On platforms where the native backend cannot programmatically close a notification, calling `notification.close()` cannot release that hold.

***

## Notification events

`Notification` instances are `EventEmitter`s. You can use `on()`, `once()`, and `off()`, or assign the shorthand property handlers directly.

```js theme={null}
notification.onclick  = ({ action }) => console.log('clicked:', action);
notification.onclose  = ()           => console.log('closed');
notification.onerror  = ({ error })  => console.error('error:', error);
notification.onshow   = ()           => console.log('shown');
```

| Event   | When it fires                                                        | Payload fields              |
| ------- | -------------------------------------------------------------------- | --------------------------- |
| `show`  | The native backend accepted and displayed the notification.          | `type`, `target`            |
| `click` | The user activated the notification body or tapped an action button. | `type`, `target`, `action?` |
| `close` | The notification was dismissed, expired, or closed programmatically. | `type`, `target`            |
| `error` | Display failed or response handling encountered an error.            | `type`, `target`, `error?`  |

The `action` field in a `click` payload is:

* `""` — the notification body was clicked (default activation).
* `"<action>"` — the `action` identifier of the button that was clicked.

**Windows note:** WebviewJS checks the global toast-notification setting before submission. If the user has disabled notifications in Windows Settings, the instance emits `error` instead of `show`. Other policies such as Do Not Disturb can still suppress presentation after the backend has accepted the notification.

***

## Closing programmatically

```js theme={null}
notification.close();
```

Programmatic closure is supported on the Linux/XDG D-Bus backend. On other platforms the call is safe but performs no native close operation; the notification remains visible until it times out or the user dismisses it.

***

## Permissions

Native application notifications do not use the browser permission model. Permission is always `'granted'`:

```js theme={null}
console.log(Notification.permission); // "granted"

const permission = await Notification.requestPermission();
console.log(permission); // "granted"
```

`Notification.requestPermission()` is a JavaScript compatibility stub. It resolves immediately with `'granted'` and never prompts the user.

***

## Platform notes

| Platform          | Image delivery                                                                                                                                        | Lifecycle events                                        |
| ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------- |
| **Linux**         | Decoded pixels sent to the notification server over D-Bus.                                                                                            | Full event support.                                     |
| **Windows**       | Temporary PNG written to disk; removed after the lifecycle ends.                                                                                      | Full event support. Check system notification settings. |
| **macOS**         | Temporary PNG written to disk; removed after the lifecycle ends.                                                                                      | Full event support.                                     |
| **Android / iOS** | JavaScript API is available and the `Notification` constructor succeeds, but no native notification is displayed and no lifecycle events are emitted. | No lifecycle events.                                    |
