How to Check the Type of a Puppeteer Dialog
Use Puppeteer’s page dialog event and dialog.type() to identify alerts, confirms, prompts, and beforeunload dialogs, then handle each safely.
To check a Puppeteer dialog’s type, listen for the page’s dialog event and call dialog.type() on the supplied Dialog object. It returns a Protocol.Page.DialogType, such as alert, confirm, prompt, or beforeunload.
page.on('dialog', async dialog => {
const type = dialog.type();
console.log(type);
await dialog.dismiss();
});
A dialog blocks page interaction until the handler accepts or dismisses it. Choose the response your application needs; the example dismisses every dialog as a simple fallback. See Puppeteer’s Dialog class reference and PageEvent reference.
1. Listen for the dialog and inspect its type
Register the handler on the Page before the action that might open a dialog. Puppeteer dispatches a Dialog instance through the page’s dialog event. Call type() inside the handler to determine which kind appeared.
import puppeteer from 'puppeteer';
const browser = await puppeteer.launch();
try {
const page = await browser.newPage();
page.on('dialog', async dialog => {
const type = dialog.type();
console.log('Dialog type:', type);
console.log('Dialog message:', dialog.message());
console.log('Prompt default:', dialog.defaultValue());
await dialog.dismiss();
});
await page.goto('https://example.com');
// Perform the action that may trigger a dialog here.
} finally {
await browser.close();
}
The listener must be installed before the triggering action; otherwise the dialog may appear before your handler is ready. The call to dismiss() ensures the handler responds. Replace it with the application-specific behavior described below.
2. Branch on the dialog type
dialog.type() returns the protocol dialog type. Use a switch so each type gets an intentional response, and keep a fallback for unexpected values as Puppeteer or the browser evolves.
page.on('dialog', async dialog => {
switch (dialog.type()) {
case 'alert':
console.log('Alert:', dialog.message());
await dialog.accept();
break;
case 'confirm':
console.log('Confirmation:', dialog.message());
await dialog.accept(); // Use dismiss() to simulate Cancel.
break;
case 'prompt':
console.log('Prompt:', dialog.message());
console.log('Default value:', dialog.defaultValue());
await dialog.accept('value to submit');
break;
case 'beforeunload':
console.log('Page requested confirmation before leaving');
await dialog.accept(); // Dismiss to remain on the page.
break;
default:
await dialog.dismiss();
}
});
Use accept() to proceed or dismiss() to cancel. For a prompt, accept(promptText) supplies the submitted text. Puppeteer documents that the optional text has no effect for other dialog types.
Dialog methods at a glance
| Method | What it tells or does |
|---|---|
type() |
Returns the dialog type. |
message() |
Returns the text shown in the dialog. |
defaultValue() |
Returns the prompt’s default value; for non-prompts it returns an empty string. |
accept(promptText?) |
Accepts the dialog. Optional text is used only for prompts. |
dismiss() |
Dismisses the dialog. |
Because defaultValue() is empty for non-prompt dialogs, it is not a reliable way to determine dialog type. Use type().
3. A complete example that triggers and handles a dialog
This runnable example creates a page with a button that opens a prompt, registers the handler first, checks the type, and supplies a response. It needs Puppeteer installed in the project (for example, npm install puppeteer).
import puppeteer from 'puppeteer';
const browser = await puppeteer.launch();
try {
const page = await browser.newPage();
page.on('dialog', async dialog => {
const type = dialog.type();
console.log({ type, message: dialog.message() });
if (type === 'prompt') {
await dialog.accept('Puppeteer response');
} else {
await dialog.dismiss();
}
});
await page.setContent(`
<button onclick="prompt('Enter a value', 'default')">Open prompt</button>
`);
await page.click('button');
console.log('Prompt was handled');
} finally {
await browser.close();
}
4. cURL, Python, and Node.js context
Puppeteer’s dialog API is a JavaScript browser automation API. It does not have a cURL or Python equivalent for controlling a Puppeteer Dialog object. Use the JavaScript examples above when the task is specifically to inspect a Puppeteer dialog.
Node.js one-off invocation
Save the complete example as dialog.mjs, install Puppeteer, then run it with Node.js:
npm install puppeteer
node dialog.mjs
Use the Puppeteer version already installed by your project when checking available types and signatures; consult the API reference for that release.
5. Timing, edge cases, and reliable handling
- Attach before navigation or interaction. Register the listener before code that could trigger the dialog.
- Always resolve the dialog. Accept or dismiss it in the event handler so the page can continue.
- Make the response type-specific. Accepting a confirmation and dismissing it represent different user choices; choose intentionally.
- Only prompts consume response text. Passing text to
accept()for another type has no effect. - Do not infer type from message text. Messages are application-controlled and can change; inspect
type(). - Do not infer type from default value. Non-prompts return an empty string, but an empty prompt default is also possible.
- Handle unexpected types. Keep a safe default branch that resolves the dialog.
There is no special performance cost to checking the type beyond handling the event. A modal dialog itself pauses page interaction while it is open, so respond promptly. For reliable automation, log the type and message when diagnosing unexpected behavior, while avoiding logging sensitive prompt content in production.
6. Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| The script hangs after a dialog appears | The dialog is not being accepted or dismissed, or the listener was added too late. | Register the handler before the action and ensure every branch awaits accept() or dismiss(). |
| The handler never runs | The page did not open a JavaScript dialog, or the listener is attached to a different Page. | Confirm the triggering action and attach the handler to the same page where it occurs. |
| A prompt receives no submitted value | The dialog was not a prompt, or the response text was not passed to accept(). |
Check dialog.type(), then call accept('value') for prompts. |
| The type appears to be missing when using TypeScript | The installed Puppeteer version’s declarations may differ from a reference for another release. | Check the installed package’s types and documentation for that version; the documented return type is Protocol.Page.DialogType. |
| A confirmation produces the wrong page behavior | The handler accepted when the expected user action was cancel, or vice versa. | Use accept() for OK/continue and dismiss() for Cancel. |
7. Or skip the browser setup
If you need a screenshot of a page rather than control of a JavaScript dialog inside a Puppeteer session, ScreenshotNeo provides a website screenshot API and MCP server. A single request captures a URL as an image or PDF, without setting up a browser runner. It does not expose Puppeteer’s dialog object or replace dialog handling in an automation flow.
For a clean capture, ScreenshotNeo accepts cookie and consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before the shot; each step can be turned off. Bot checks and CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and the response identifies the page verdict and billing status in headers. Its MCP server offers take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 shots.
cURL:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com -o shot.webp
Python:
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://example.com"},
timeout=90,
)
open("shot.webp", "wb").write(r.content)
Node.js:
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://example.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await Bun.write('shot.webp', new Uint8Array(await res.arrayBuffer()));
See the ScreenshotNeo API documentation for request options. Create a free ScreenshotNeo account to get 1,000 screenshots a month with no card.
FAQ
What does dialog.type() return?
It returns a Protocol.Page.DialogType identifying the dialog kind.
Can I get the prompt’s initial text?
Yes. Call dialog.defaultValue(); it returns an empty string for dialogs that are not prompts.
Does ScreenshotNeo inspect Puppeteer dialogs?
No. ScreenshotNeo captures a URL as an image or PDF; use Puppeteer’s dialog event when you need to inspect or respond to a browser dialog.


