# How to Manage Page Dialogs (Alerts, Prompts, Confirms) in Ego-Browser

> Learn how to manage page dialogs alerts prompts and confirms in ego-browser using the pendingDialog helper and pageInfo API with Chrome DevTools Protocol commands.

- Repository: [CitroLabs/ego-lite](https://github.com/citrolabs/ego-lite)
- Tags: how-to-guide
- Published: 2026-07-30

---

**Ego-Browser exposes JavaScript dialogs through the `pendingDialog()` helper and `pageInfo()` API, allowing you to accept or dismiss them via Chrome DevTools Protocol commands.**

Managing page dialogs like alerts and prompts in ego-browser requires interacting with the Chrome DevTools Protocol (CDP) to detect and respond to JavaScript dialog events. The **citrolabs/ego-lite** runtime tracks these dialogs in a per-session map and provides helper functions to inspect their state. This guide explains how to detect, inspect, and handle alert, confirm, and prompt dialogs using the library's core APIs.

## How Ego-Browser Tracks JavaScript Dialogs

The runtime listens for CDP events to maintain dialog state. When a page triggers `alert()`, `confirm()`, `prompt()`, or `beforeunload`, Chrome emits the `Page.javascriptDialogOpening` event.

In [`browser-runtime.ts`](https://github.com/citrolabs/ego-lite/blob/main/browser-runtime.ts), this event updates an internal `pendingDialogs` map that stores the dialog payload for the active session. The runtime automatically removes the entry when the `Page.javascriptDialogClosed` event fires, ensuring you don't need to manually clean up state after handling a dialog.

The `pendingDialog()` function exported from [`browser-runtime.ts`](https://github.com/citrolabs/ego-lite/blob/main/browser-runtime.ts) exposes the current dialog object, if any, to your automation code.

## Detecting Dialogs with pageInfo() and pendingDialog()

To check whether a dialog is blocking the page, use either the high-level `pageInfo()` helper or the direct `pendingDialog()` accessor.

The `pageInfo()` function defined in [`driver/nav.ts`](https://github.com/citrolabs/ego-lite/blob/main/driver/nav.ts) returns a dialog object alongside page metadata when a dialog is present. Alternatively, import `pendingDialog()` from [`browser-runtime.ts`](https://github.com/citrolabs/ego-lite/blob/main/browser-runtime.ts) to access the raw dialog state directly.

A dialog object contains the following fields:

- **type** – The dialog variant: `alert`, `confirm`, `prompt`, or `beforeunload`
- **message** – The string message displayed to the user
- **defaultPrompt** – For `prompt` dialogs only, the default input text

## Accepting or Dismissiving Dialogs via CDP

Once detected, interact with the dialog using the CDP method `Page.handleJavaScriptDialog`. Import the `cdp()` helper from [`cdp-eval.ts`](https://github.com/citrolabs/ego-lite/blob/main/cdp-eval.ts) to send commands to the browser.

The payload requires an `accept` boolean:

- Set `accept: true` to click "OK" or confirm the action
- Set `accept: false` to dismiss or cancel the dialog

For `prompt` dialogs, include a `promptText` string containing the value to enter into the input field.

```typescript
import { cdp } from "ego-browser/src/cdp-eval.js";

// Accept an alert or confirm
await cdp("Page.handleJavaScriptDialog", { accept: true });

// Dismiss a confirm dialog (click Cancel)
await cdp("Page.handleJavaScriptDialog", { accept: false });

// Answer a prompt dialog
await cdp("Page.handleJavaScriptDialog", {
  accept: true,
  promptText: "my custom answer"
});

```

## Complete Code Examples

### Accepting an Alert Dialog

Detect an alert using `pageInfo()` and accept it to continue page execution:

```typescript
import { cdp } from "ego-browser/src/cdp-eval.js";
import { pageInfo } from "ego-browser/src/driver/nav.js";

async function acceptCurrentDialog() {
  const info = await pageInfo();
  if ("dialog" in info) {
    await cdp("Page.handleJavaScriptDialog", { accept: true });
    console.log("Dialog accepted");
  } else {
    console.log("No dialog present");
  }
}

```

### Dismissing a Confirmation and Capturing Its Message

Use `pendingDialog()` to inspect the message before dismissing:

```typescript
import { cdp } from "ego-browser/src/cdp-eval.js";
import { pendingDialog } from "ego-browser/src/browser-runtime.js";

async function dismissConfirmAndLog() {
  const dialog = pendingDialog();
  if (dialog && dialog.type === "confirm") {
    console.log("Confirm message:", dialog.message);
    await cdp("Page.handleJavaScriptDialog", { accept: false });
  }
}

```

### Responding to a Prompt with Custom Text

Check for `type: "prompt"` and supply the `promptText` parameter:

```typescript
import { cdp } from "ego-browser/src/cdp-eval.js";
import { pendingDialog } from "ego-browser/src/browser-runtime.js";

async function answerPrompt() {
  const dlg = pendingDialog();
  if (dlg && dlg.type === "prompt") {
    await cdp("Page.handleJavaScriptDialog", {
      accept: true,
      promptText: "my custom answer"
    });
  }
}

```

## Handling Dialogs in Automation Workflows

The screenshot helper in [`driver/observe.ts`](https://github.com/citrolabs/ego-lite/blob/main/driver/observe.ts) demonstrates defensive dialog handling. The `screenshot()` function checks `pendingDialog()` before capturing; if a dialog is present, it switches to a "raw" screenshot mode to avoid clipping the overlay.

This pattern ensures your automation remains robust when unexpected alerts appear during visual regression testing or page observation tasks.

## Summary

- **Track dialogs** using the `Page.javascriptDialogOpening` event handled internally in [`browser-runtime.ts`](https://github.com/citrolabs/ego-lite/blob/main/browser-runtime.ts)
- **Detect state** by calling `pageInfo()` from [`driver/nav.ts`](https://github.com/citrolabs/ego-lite/blob/main/driver/nav.ts) or `pendingDialog()` from [`browser-runtime.ts`](https://github.com/citrolabs/ego-lite/blob/main/browser-runtime.ts)
- **Interact** via `cdp("Page.handleJavaScriptDialog", { accept: boolean, promptText?: string })` imported from [`cdp-eval.ts`](https://github.com/citrolabs/ego-lite/blob/main/cdp-eval.ts)
- **Automatic cleanup** occurs when the runtime receives `Page.javascriptDialogClosed`, so manual state management is unnecessary

## Frequently Asked Questions

### How do I detect if a dialog is currently open?

Call `await pageInfo()` and check if the returned object contains a `dialog` key, or import `pendingDialog()` from [`browser-runtime.ts`](https://github.com/citrolabs/ego-lite/blob/main/browser-runtime.ts) to get the dialog object directly. Both methods return `null` or `undefined` when no dialog is active.

### Can I handle beforeunload dialogs using the same API?

Yes. The `type` field in the dialog object includes `beforeunload` alongside `alert`, `confirm`, and `prompt`. Use the same `Page.handleJavaScriptDialog` CDP command to accept or dismiss beforeunload confirmations.

### What happens if I don't handle the dialog?

If ignored, the dialog remains pending and blocks page execution. The `pendingDialogs` map in [`browser-runtime.ts`](https://github.com/citrolabs/ego-lite/blob/main/browser-runtime.ts) retains the entry until the dialog is dismissed via CDP or the page context is destroyed.

### How do I capture the message text from a confirmation dialog?

Access the `message` property on the object returned by `pendingDialog()` or `pageInfo()`. This field contains the exact string passed to the JavaScript `confirm()` or `alert()` call.