Puppeteer provides a powerful event-driven architecture that allows you to listen for and handle various browser and page events. Both page
and browser
objects emit events that you can subscribe to for monitoring, debugging, and controlling browser behavior.
Page Events
Console Events
Monitor all console output from the web page:
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
page.on('console', (msg) => {
console.log(`[${msg.type()}] ${msg.text()}`);
// Handle different console levels
if (msg.type() === 'error') {
console.error('Page Error:', msg.text());
}
});
await page.goto('https://example.com');
await browser.close();
})();
Dialog Events
Handle JavaScript dialogs (alert, confirm, prompt):
page.on('dialog', async (dialog) => {
console.log(`Dialog type: ${dialog.type()}`);
console.log(`Dialog message: ${dialog.message()}`);
// Handle different dialog types
switch (dialog.type()) {
case 'alert':
await dialog.accept();
break;
case 'confirm':
await dialog.accept(); // or dialog.dismiss()
break;
case 'prompt':
await dialog.accept('Your input here');
break;
case 'beforeunload':
await dialog.accept();
break;
}
});
Network Events
Monitor network requests and responses:
// Request event
page.on('request', (request) => {
console.log(`→ ${request.method()} ${request.url()}`);
// Filter by resource type
if (request.resourceType() === 'image') {
console.log('Image request:', request.url());
}
});
// Response event
page.on('response', (response) => {
console.log(`← ${response.status()} ${response.url()}`);
// Handle failed requests
if (!response.ok()) {
console.error(`Failed request: ${response.status()} ${response.url()}`);
}
});
// Request failed event
page.on('requestfailed', (request) => {
console.error(`Request failed: ${request.url()} - ${request.failure().errorText}`);
});
Error Events
Handle uncaught page errors:
page.on('error', (error) => {
console.error('Page crashed:', error.message);
});
page.on('pageerror', (error) => {
console.error('Page error:', error.message);
});
Browser Events
Browser Close Events
Handle browser closure:
browser.on('disconnected', () => {
console.log('Browser has been disconnected');
});
browser.on('targetcreated', (target) => {
console.log('New target created:', target.url());
});
browser.on('targetdestroyed', (target) => {
console.log('Target destroyed:', target.url());
});
Complete Example
Here's a comprehensive example that demonstrates multiple event handlers:
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({ headless: false });
const page = await browser.newPage();
// Set up all event listeners BEFORE navigation
page.on('console', msg => {
console.log(`[CONSOLE ${msg.type()}]:`, msg.text());
});
page.on('dialog', async dialog => {
console.log(`[DIALOG ${dialog.type()}]:`, dialog.message());
await dialog.accept();
});
page.on('request', request => {
console.log(`[REQUEST]: ${request.method()} ${request.url()}`);
});
page.on('response', response => {
if (!response.ok()) {
console.error(`[RESPONSE ERROR]: ${response.status()} ${response.url()}`);
}
});
page.on('requestfailed', request => {
console.error(`[REQUEST FAILED]: ${request.url()}`);
});
page.on('error', error => {
console.error('[PAGE ERROR]:', error.message);
});
page.on('pageerror', error => {
console.error('[PAGE SCRIPT ERROR]:', error.message);
});
// Navigate to page
await page.goto('https://example.com');
// Trigger some events for demonstration
await page.evaluate(() => {
console.log('Hello from the page!');
console.error('This is an error message');
// alert('This is an alert!'); // Uncomment to test dialog handling
});
await browser.close();
})();
Best Practices
Add listeners before navigation: Always set up event listeners before calling
page.goto()
to capture all events from the initial page load.Handle async operations: Dialog events require async handling, so always use
async/await
when accepting or dismissing dialogs.Filter events: Use conditional logic to handle only relevant events, especially for request/response monitoring.
Error handling: Always include error event handlers to prevent crashes and get debugging information.
Resource cleanup: Remove event listeners when they're no longer needed to prevent memory leaks:
const handler = (msg) => console.log(msg.text());
page.on('console', handler);
// Later...
page.off('console', handler);
Event Timing
Events fire in this typical order:
1. request
- When a request is initiated
2. response
- When a response is received
3. console
- When page scripts log to console
4. dialog
- When page shows a dialog
5. error
/pageerror
- When errors occur
Understanding this event flow helps you build robust web scraping and testing applications with Puppeteer.