Get the iframe’s Puppeteer Frame, then create and click the locator from that frame—not from the top-level page. For a page with an iframe identified as iframe#payment:
const iframe = await page.$('iframe#payment');
const frame = await iframe?.contentFrame();
if (!frame) {
throw new Error('Iframe frame not found');
}
await frame.locator('button.submit').click();
ElementHandle.contentFrame() returns the frame associated with an iframe element. Puppeteer’s interaction guide recommends locators because they wait for an element to be ready for an action. ElementHandle.contentFrame() · Page interactions
Why the click must run in the iframe’s frame
An iframe has its own document. A locator created from page searches the page’s main frame; it does not automatically look inside an iframe. First obtain the iframe’s Puppeteer Frame, then create the target locator from that frame.
The documented API pattern is to query the iframe element and call contentFrame(). The target selector is then evaluated in that frame’s document. Frame API · ElementHandle.contentFrame()
Recommended Free Tools
#1 Best Overall
Click an element in a known iframe
This complete example assumes page is an existing Puppeteer Page and the iframe has the CSS selector iframe#checkout. Replace both selectors with ones that match the page you are automating.
const iframeHandle = await page.$('iframe#checkout');
if (!iframeHandle) {
throw new Error('Checkout iframe element not found');
}
const frame = await iframeHandle.contentFrame();
if (!frame) {
throw new Error('Checkout iframe frame not available');
}
await frame.locator('button[type="submit"]').click();
The two checks distinguish a missing iframe element from an unavailable associated frame. Although the API reference says an associated frame exists for an HTML iframe element, the general return type can be null, so checking is useful defensive code. ElementHandle.contentFrame()
Use a locator for the interaction
Locators are Puppeteer’s recommended way to select and interact with elements. They automatically wait for the element to be present and action-ready, including being visible, enabled, in the viewport, and having a stable bounding box before a click. Create the locator from frame, as in frame.locator('button[type="submit"]'). Page interactions
Rank #2
Use Frame.click() when you need the lower-level method
You can also call await frame.click('button[type="submit"]'). The Frame API’s selector-based click acts on the first matching element and rejects if it finds no match. If multiple elements could match, narrow the selector; if you need locator readiness and retry behavior, use a locator instead. Frame API
Wait for navigation caused by the click
If clicking the target is expected to navigate the iframe, begin waiting for navigation and perform the click together with Promise.all. This prevents the click from triggering navigation before Puppeteer starts listening for it:
const [response] = await Promise.all([
frame.waitForNavigation(),
frame.locator('button[type="submit"]').click(),
]);
Use this only when the action is expected to navigate that frame. If it does not navigate, simply await the locator click. Puppeteer documents the concurrent pattern for navigation triggered indirectly by an action and warns that starting the wait separately can race. Frame API
Find the iframe when its name is the reliable identifier
If the iframe selector is unknown or unstable but its name is known, enumerate the page’s frames, inspect each frame’s iframe element, and keep the matching frame:
let targetFrame;
for (const candidate of page.frames()) {
const element = await candidate.frameElement();
const name = await element.evaluate(el => el.getAttribute('name'));
if (name === 'myframe') {
targetFrame = candidate;
break;
}
}
if (!targetFrame) {
throw new Error('Named frame not found');
}
await targetFrame.locator('.selector').click();
Replace myframe and .selector with the expected frame name and target selector. Puppeteer also exposes page.mainFrame() and Frame.childFrames() for inspecting the frame tree. Frame API
Click into a nested iframe
If the target is in an iframe inside another iframe, the outer frame is not the target document. Inspect the known parent frame’s childFrames() or inspect page.frames(), identify the innermost frame that contains the target, and create the locator from that frame.
Rank #4
Each frame has its own document context: a selector used in a parent frame does not cross into a nested iframe. Puppeteer’s Frame API describes frames as potentially nested and provides childFrames() for traversal. Frame API
Choose and validate the target selector
CSS selectors work by default. Puppeteer also supports additional selector syntax, including text and accessibility attributes. Use a specific selector grounded in the page’s markup, especially when several controls in a frame have similar labels or types. Page interactions
When a locator times out, do not assume that adding a fixed delay is the right fix. Check whether you selected the right frame, whether the selector matches the intended element, and whether the page reached the state in which the element is ready. The interaction guide documents locator retry and timeout behavior. Page interactions
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Fix the driver behind crashes, sound loss and screen glitches3Repair Windows errors before they cause bigger problemsBest Value
- Used Book in Good Condition
Troubleshoot common iframe click failures
- The element is not found from
page:pagesearches the main frame. Get the iframe’sFrameand create the locator from it. - The iframe lookup selects the wrong frame: Narrow the iframe selector or identify the frame using its name or other known information. Pages can contain multiple frames.
- The target is in a nested iframe: Traverse into the child frame containing the target and use that innermost frame’s locator.
- The click times out: Verify frame identity and selector first, then confirm the page reaches the required state. A locator waits for action readiness; an arbitrary delay does not correct a wrong frame or selector.
- The click causes navigation but the script misses it: Put
frame.waitForNavigation()and the click in the samePromise.all. - The click hits the wrong match: Make the selector more specific. The lower-level
Frame.click()clicks the first match. - The frame was detached or replaced: Pages can attach, navigate, or detach frames. Reacquire the current frame after the page rebuilds it instead of retaining an old frame reference indefinitely.
Puppeteer dispatches FrameAttached, FrameNavigated, and FrameDetached lifecycle events on the parent page. Frame API
Or skip the browser setup
If you need a screenshot rather than an in-browser click, ScreenshotNeo can return an image or PDF from one GET request. This does not click controls or replace Puppeteer interactions.
For example, save a screenshot of a page as WebP:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo API documentation for request options. Before capture, it accepts cookie or consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and responses indicate the page verdict and billing status in headers. An MCP server provides take_screenshot, get_page_info, and capture_pdf tools for AI agents and MCP clients. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000.
Create a free ScreenshotNeo account to try 1,000 screenshots a month with no card.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Frequently Asked Questions
Does Puppeteer’s page locator search inside an iframe?
No. A locator created from the top-level page searches its main frame. Get the iframe’s Frame and create the locator from that frame.
What should I do if a frame is replaced while my script is running?
Reacquire the current frame after the page replaces or detaches the old one; do not rely indefinitely on a stale frame reference.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

