October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsPC HealthRecommendedCrashes, freezes, slowdowns? Check your PC nowSpot repairable issues before they interrupt work.Check PCOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk5 min

How to Run JavaScript in an Iframe with Puppeteer

Use Puppeteer’s Frame API to execute JavaScript inside an iframe, with runnable examples for contentFrame(), evaluate(), and common frame-loading problems.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use Puppeteer’s Frame API to run JavaScript inside an iframe: get the iframe’s frame with contentFrame(), then call frame.evaluate(). page.evaluate() runs in the main page’s frame, so it won’t select elements inside a separate iframe. See the Puppeteer Frame API and ElementHandle API.

Run JavaScript in an iframe by getting its Frame

This example waits for an identifiable iframe, maps its element to a Puppeteer Frame, waits for content inside it, and reads that content from the frame’s browser context:

As an Amazon Associate I earn from qualifying purchases.

const iframeElement = await page.waitForSelector('iframe#app-frame');
if (!iframeElement) throw new Error('Iframe element was not found');

const frame = await iframeElement.contentFrame();
if (!frame) throw new Error('Iframe frame was not available');

await frame.waitForSelector('#status');
const status = await frame.evaluate(() => {
  return document.querySelector('#status')?.textContent?.trim() ?? null;
});
console.log(status);

contentFrame() resolves the frame associated with an iframe element. The null checks distinguish an iframe selector that did not produce an element from an element whose frame was not available. frame.waitForSelector() waits for the expected element within that frame.

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

Why page.evaluate() does not see iframe content

page.evaluate() runs in the page’s main frame. An iframe has its own Frame context, so querying for an element that exists only inside that iframe from the main frame will not find it. Call frame.evaluate() on the target frame instead. Puppeteer describes it as: “Behaves identically to Page.evaluate() except it’s run within the context of this frame.”

Choose the target frame

Use contentFrame() when the iframe element is identifiable

If you can select the iframe reliably, contentFrame() is the direct route. Wait for the iframe element, call contentFrame(), and check that the returned frame is available before evaluating code.

Inspect page.frames() when frame properties are a better signal

When the iframe is easier to identify by its URL or another frame-level property than by a DOM selector, inspect page.frames() and choose the matching frame. You can also navigate the tree from page.mainFrame() through childFrames(). For nested iframes, each child is a separate frame: obtain the particular child frame where the target content lives before running code there.

Pass Node.js values into evaluate()

The function passed to evaluate() is serialized and executed in the browser context. It cannot close over variables or helper functions from Node.js lexical scope. Pass values as arguments instead:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
const result = await frame.evaluate((label) => {
  return `${label}: ${document.title}`;
}, 'iframe title');

console.log(result);

The browser executes the callback, and Puppeteer returns its result to Node.js. Puppeteer awaits a promise returned by the callback. Primitive results can be transferred directly, and ordinary objects are serialized; a DOM node is not returned as a live DOM object. If you need a live browser-side object, use an evaluation handle rather than expecting a returned node to remain usable in Node.js. See the Puppeteer evaluate API.

Evaluate against an element with $eval()

For a one-off operation on the first matching element in the frame, use frame.$eval(selector, fn):

const status = await frame.$eval('#status', element => {
  return element.textContent?.trim() ?? null;
});

Use this when the task is confined to that element. Use frame.evaluate() when the code needs broader access to the frame’s document or multiple elements.

Handle navigation, loading, and nested frames

  • Wait for the content you need. A frame can exist before its target element is ready. Use frame.waitForSelector() before evaluating against that content; Puppeteer documents that it works across navigations.
  • Reacquire after significant navigation. Frames can attach, navigate, or detach. A reference may no longer represent the document you expect after navigation, so wait for the expected state and get the current frame again when needed.
  • Target nested frames explicitly. Evaluating in a parent frame does not automatically run code in its child iframe. Locate the child frame and evaluate in that context.

Troubleshoot common failures

Symptom Likely cause What to do
contentFrame() returns null The iframe element is not available as a frame at that point, or the page is changing. Confirm the selector identifies the iframe, wait for it, check the return value, and retry after the expected page state if navigation is in progress.
Selector works on the page but not in the iframe The query is running in the main frame or in the wrong child frame. Obtain the target iframe’s Frame and run waitForSelector(), $eval(), or evaluate() on that frame.
Evaluation runs but a Node.js variable is undefined The browser-side callback cannot use Node.js lexical-scope variables. Pass the value as an explicit argument to evaluate(fn, value).
Evaluation fails after a page transition The frame navigated or detached, leaving the reference stale for the expected document. Wait for the transition and reacquire the iframe’s current frame before continuing.
Code in a parent frame misses content in a nested iframe The nested iframe is a separate child frame. Traverse the frame tree or inspect page.frames(), identify the child, and evaluate there.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

If your goal is to capture a page rather than execute custom code inside its iframe, ScreenshotNeo can return a screenshot or PDF with one GET request. Its clean-shot workflow accepts cookie and consent banners like a visitor and removes known consent platforms, newsletter popups, and chat widgets before capture; those steps can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers report the page verdict and billing status. It also offers an MCP server for AI agents and includes 1,000 screenshots per month on the free plan with no card; paid plans start at $5 for 3,000.

Free tools Windows power users keep installed

One-click scans. No signup required.

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

Example using cURL (replace the URL with the page you want to capture):

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. Sign up for 1,000 free screenshots a month with no card.

Best Value
The SQL Programming Language: .
  • Used Book in Good Condition

Frequently Asked Questions

Can Puppeteer run JavaScript inside a cross-origin iframe?

This guide establishes how to select a Puppeteer frame and evaluate code in its browser context; it does not establish detailed same-origin or sandbox behavior. Check the browser and iframe’s applicable security restrictions for your case.

Does frame.evaluate() return a DOM element I can use in Node.js?

No. Returned DOM nodes are not transferred as live DOM objects. Return serializable data, or use an evaluation handle when you need a live browser-side object.

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

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.

Leave a Reply

Your email address will not be published. Required fields are marked *

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

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Windows Errors? Fix Them Before They SpreadFree repair scan
Crashes, No Sound, or Screen Glitches?Free driver scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.