Puppeteer ClickOptions: Click Settings Explained
Learn what Puppeteer ClickOptions control, how offsets and repeated clicks work, and how to coordinate clicks with navigation reliably.
Puppeteer’s ClickOptions lets you configure the mouse input used for a click: its target point, mouse button, number of clicks, and press duration. It also has an experimental visual debugging option. These settings do not wait for the page to become ready. When a click may navigate, start waitForNavigation() at the same time as the click.
This guide follows the live Puppeteer API references: ClickOptions, MouseClickOptions, and Page.click() show version 25.12.0; MouseOptions shows 25.10.0; Offset shows 25.2.1; and LocatorClickOptions shows 25.9.0. Check the live reference for the version installed in your project: ClickOptions, Page.click().
1. What are Puppeteer ClickOptions?
ClickOptions extends MouseClickOptions, which extends MouseOptions. The resulting options are a small set of controls over mouse-click behavior:
| Option | What it controls | Default or caveat |
|---|---|---|
offset |
Point within the target element to click. | Without an offset, Page.click() clicks the element’s center. |
button |
Which mouse button to press. | Defaults to 'left'. |
count |
How many click inputs to send. | Defaults to 1. |
delay |
Time between mouse press and release, in milliseconds. | It is press duration, not a wait before or after the click. |
debugHighlight |
Shows a visual highlight at the click location. | Experimental; lasts 10 seconds and does not persist across navigation. |
These options describe input. They do not wait for a selector, network idle, or navigation. Add the appropriate explicit wait when the application needs one.
2. Click an element with Page.click()
Page.click(selector, options) finds the matching element, scrolls it into view if needed, and clicks its center by default. If several elements match, it clicks the first. If no element matches, the returned promise rejects.
Runnable JavaScript example using Puppeteer:
import puppeteer from 'puppeteer';
const browser = await puppeteer.launch({ headless: true });
try {
const page = await browser.newPage();
await page.goto('https://example.com');
await page.click('button.submit', {
button: 'left',
count: 1,
delay: 0,
offset: { x: 12, y: 8 },
});
} finally {
await browser.close();
}
The offset values are illustrative: use coordinates appropriate to the element’s dimensions. If the desired point is the center, omit offset.
3. How do I set the click offset in Puppeteer?
Set offset to an object with x and y. Its origin is the top-left corner of the element’s border box. It is not an adjustment from Puppeteer’s default center point.
await page.click('.canvas-control', {
offset: { x: 18, y: 10 },
});
Use an offset when an element’s center is not the intended hit target, such as clicking a particular region of a larger control. Confirm the element’s rendered size and layout: a point outside the element, or over an overlapping element, may not activate the intended target. Dynamic layouts can also move the target between locating it and clicking.
4. How do I double-click with Puppeteer?
Set count to 2 to send a double-click input:
await page.click('.file-name', { count: 2 });
The API defines the click count, but the application decides what that input means. It may select text, open a file, or do something else. Use this only when repeated click input is intended, and do not assume every site handles it identically.
5. Choosing the mouse button and press duration
button selects the mouse button; its default is 'left'. delay sets how many milliseconds elapse between pressing and releasing the mouse button. For example:
await page.click('.context-target', {
button: 'right',
delay: 100,
});
A non-default button or longer press is only useful when the page’s interaction is designed to respond to that input. A longer delay does not pause before the click and does not wait for the resulting UI. Add a separate wait for the specific result if needed.
6. Using debugHighlight
debugHighlight: true asks Puppeteer to insert a visible highlight at the click location for 10 seconds. The reference marks it experimental: it may not work on every page and will not persist across navigations.
await page.click('button.save', { debugHighlight: true });
Use this to inspect where the action is aimed while debugging. It does not make the click more reliable, verify that the page accepted it, or synchronize with navigation. Turn it off for ordinary runs if the visible mark is not useful.
7. How do I click a button and wait for navigation in Puppeteer?
Register the navigation wait before the click can trigger it. Puppeteer documents using Promise.all() so both operations start together:
const [response] = await Promise.all([
page.waitForNavigation(),
page.click('a.next'),
]);
This avoids a race where a click starts navigation before a separately started wait is registered. Choose navigation wait options that match the application. A client-side route change, a full document navigation, and a page that keeps connections open may need different readiness conditions. Do not add a generic delay as a substitute for waiting on the actual outcome you need.
8. Page.click(), element handles, and locators
Page.click() is selector-based: it finds a match, scrolls it into view, then uses the page mouse to click. An ElementHandle click acts on an element handle you already obtained, so the element lookup and its failure conditions are separate from Page.click().
Locators have a related type, LocatorClickOptions, defined as ClickOptions & ActionOptions. It includes an optional AbortSignal for aborting the locator action. That signal belongs to the locator action options; do not assume it is a universal field on every ClickOptions call surface. See the official LocatorClickOptions reference.
9. Troubleshooting common click problems
| Symptom | Likely cause | What to do |
|---|---|---|
Page.click() rejects because the selector was not found. |
The element is absent, appears later, or the selector does not match. | Check the selector and wait for the element using the page or locator wait appropriate to the page. |
| The click lands in the wrong part of the control. | The default center is unsuitable, or the offset was treated as center-relative. | Measure from the border-box top-left and set an in-bounds {x, y} offset. |
| The click does not activate the expected behavior. | The chosen point is covered, the page has changed layout, or the application expects another input. | Inspect the rendered target, use debugHighlight as a visual aid, and verify the expected mouse button and click count. |
| The navigation wait times out or misses the transition. | The wait was registered after the click, or the site’s transition does not match the chosen navigation condition. | Start click and navigation wait together with Promise.all(); select a condition suitable for the site. |
| A double-click behaves differently across pages. | The API sends repeated click input, but application behavior varies. | Check the page’s intended interaction and use count: 2 only where appropriate. |
| The highlight is absent or disappears. | The feature is experimental, unsupported on that page, or navigation replaced the page. | Treat it as a temporary debugging aid, not a persistent marker or correctness check. |
10. Reliability, performance, and cost considerations
Click options do not provide readiness guarantees. Reliable automation pairs the input with a condition that proves the desired result: for example, a navigation response, a visible confirmation, or a changed element state. Prefer a condition tied to the application outcome over arbitrary sleeps. Re-check selectors and offsets when responsive layout or content changes can move the target.
The cited API references define behavior but provide no benchmark statistics. The options themselves are not a performance tuning system. Repeated clicks, long press durations, and debug highlighting should represent the input the page needs, rather than being added speculatively. Puppeteer is browser automation and requires browser setup and execution resources; the API reference does not specify a universal cost or runtime because those depend on your environment and workload.
11. Or skip the browser setup
If the goal is to capture a page rather than interact with it, ScreenshotNeo provides a website screenshot API and MCP server. One GET request returns a screenshot or PDF, and the parameter names used by other screenshot APIs also work. See the ScreenshotNeo site and API documentation.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
timeout=90,
)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.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', res);
Cookie banners, popups, and chat widgets are removed before the shot, and each step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits are never billed; response headers report the page verdict and billing status. An MCP server lets AI agents use take_screenshot, get_page_info, and capture_pdf. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 shots. Every feature is on every plan.
Sign up for 1,000 free screenshots a month, with no card required.
12. Frequently asked questions
Does ClickOptions wait for an element to appear?
No. The options configure mouse input. Element lookup and waiting are handled by the relevant page or locator operation.
Does offset mean pixels from the click center?
No. Its origin is the top-left of the target’s border box.
Is debugHighlight suitable for production synchronization?
No. It is an experimental visual debugging aid and does not confirm that an action succeeded.
Can I use AbortSignal with every Puppeteer click?
The documented signal is part of LocatorClickOptions through ActionOptions; it is not listed as a universal ClickOptions property.


