Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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()

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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

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

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

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

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Best Value
The SQL Programming Language: .
  • Used Book in Good Condition
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshoot common iframe click failures

  • The element is not found from page: page searches the main frame. Get the iframe’s Frame and 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 same Promise.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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

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.