Driver FixRecommendedSound, Wi-Fi or graphics acting up? Check drivers firstFind missing or outdated drivers fast.Check DriversOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsSlow PC?RecommendedPC slow today? Run a repair scan before it gets worseResolve common Windows issues and optimize system performance.Scan Now×
Skip to content
World desk5 min

How to Run JavaScript in a Puppeteer Frame

Use Puppeteer’s Frame.evaluate() to execute JavaScript in the intended frame. Learn frame selection, arguments, waiting, handles, and common fixes.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Run browser-side JavaScript in the frame you want by calling await frame.evaluate(callback, ...args). Select the right Puppeteer Frame first; pass Node.js values as arguments, because the callback runs in the browser context and cannot access variables from your Node.js scope.

Run JavaScript in a frame

Use frame.evaluate() for code that should run inside an iframe or the main frame. Puppeteer serializes the callback, evaluates it in that frame’s browser context, waits for a returned promise to resolve, and sends the result back to Node.js if it can be serialized. See the Frame.evaluate() API reference and JavaScript execution guide.

const frame = page.frames().find(candidate => candidate.url().includes('/widget'));
if (!frame) throw new Error('Target frame was not found');

const title = await frame.evaluate(() => document.title);
console.log(title);

The callback executes against the selected frame’s document, not automatically against every frame on the page. For the top-level document, use page.mainFrame(); for child frames, locate the relevant frame through page.frames() or the frame tree.

Pass Node.js values into the frame

Variables in the Node.js module are not in scope inside the serialized browser callback. Pass values as trailing arguments to evaluate() instead.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
const selector = '.status';
const status = await frame.evaluate(
  selector => document.querySelector(selector)?.textContent?.trim() ?? null,
  selector,
);

console.log(status);

Keep the callback self-contained or pass each needed value explicitly. A helper function declared in Node.js is not available inside the browser callback unless you pass its data and define the logic in the callback itself. The function and argument behavior is documented in the Frame.evaluate() reference and JavaScript execution guide.

Find and wait for the intended frame

Frames can attach, navigate, and detach while a page is running. A URL match is convenient when the frame URL is distinctive, but inspecting the iframe element can be more reliable when several frames have similar URLs.

Select by URL

const frame = page.frames().find(candidate => candidate.url().includes('/checkout'));
if (!frame) throw new Error('Checkout frame not found');

await frame.waitForSelector('[data-ready="true"]');
const result = await frame.evaluate(() => ({
  title: document.title,
  ready: document.querySelector('[data-ready="true"]') !== null,
}));

console.log(result);

frame.waitForSelector() waits for matching content in that frame, including across navigations; it throws if the required element does not appear. See the Frame.waitForSelector() reference.

Select through the iframe element

To identify a frame by its iframe’s name or id, inspect each candidate’s frame element. The current Frame reference recommends reading those attributes from the element rather than relying on the deprecated frame.name() method.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
for (const candidate of page.frames()) {
  const frameElement = await candidate.frameElement();
  if (!frameElement) continue;

  const nameOrId = await frameElement.evaluate(el => el.name || el.id);
  if (nameOrId === 'payment-frame') {
    const result = await candidate.evaluate(() => document.body.innerText);
    console.log(result);
    break;
  }
}

Use childFrames() and parentFrame() when you need to understand nesting. Evaluating in a parent frame does not automatically execute in its nested child frames. Frame navigation and frame-element methods are covered in the Frame class reference.

Choose the right frame API

Method Best for What comes back Waiting behavior
frame.evaluate(fn, ...args) Arbitrary JavaScript in a frame A serialized result Awaits a returned promise; wait for dynamic elements separately
frame.evaluateHandle(fn, ...args) Keeping a reference to a DOM node or other browser object A handle to a browser object Does not replace an explicit content wait
frame.$eval(selector, fn, ...args) / frame.$$eval(selector, fn, ...args) Running a function on the first matching element or on matching elements The function’s serialized result Targets matching elements; use an explicit wait if content is dynamic
frame.waitForSelector(selector, options) Waiting for matching frame content An element handle, or null for the documented hidden case Waits for the selector; throws if required content does not appear
frame.locator(selector) Interactions such as clicking or filling A locator for the target Automatically waits for presence and state as needed

Use evaluate() when the task calls for custom browser-side JavaScript. For direct interaction, a locator is generally preferable because it handles waiting and state checks. The Page interactions guide explains locators, and the Frame.$eval() reference documents element-focused evaluation.

Return data or keep a live browser object

Ordinary evaluate() returns values that Puppeteer can serialize, such as strings, numbers, arrays, and plain objects. A DOM node returned this way is not a usable live node in Node.js. Use evaluateHandle() when you need to retain a reference to the browser object.

const bodyHandle = await frame.evaluateHandle(() => document.body);
try {
  const text = await bodyHandle.evaluate(body => body.innerText);
  console.log(text);
} finally {
  await bodyHandle.dispose();
}

Handles are disposed when their associated frame navigates away or their parent context is destroyed. Dispose of handles when finished to release them promptly. See the JavaScript execution guide and Frame class reference.

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 frame evaluation

  • The callback says a Node variable is undefined: pass it as an argument, for example frame.evaluate(value => document.title + value, value). The callback runs in the browser context.
  • The result is an empty object or is not a DOM node: return serializable data for ordinary evaluate(); use evaluateHandle() for a live browser-object reference.
  • A selector is missing: confirm you selected the correct frame, then wait with frame.waitForSelector(selector). If it never appears, the wait can time out. For clicks and fills, consider a locator.
  • The script reads the wrong page: inspect frame.url() or the candidate’s iframe name/id; the top-level page’s DOM does not contain a child frame’s document.
  • The content is in a nested iframe: find that nested frame in the frame tree and call evaluate() on it directly.
  • A saved handle stops working after navigation: navigation or context destruction disposes associated handles. Acquire a new handle after navigation and dispose of old ones when finished.

Or skip the browser setup

If the goal is to capture a page rather than run custom JavaScript in its frame, ScreenshotNeo provides a screenshot API and MCP server. This one-call example returns a screenshot file; see the API documentation for options.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

ScreenshotNeo can accept cookie or consent banners and remove known consent platforms, newsletter popups, and chat widgets before capture. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed. Its MCP server lets AI agents use screenshot and PDF tools. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000.

Sign up for ScreenshotNeo’s free plan to try 1,000 screenshots a month without a card.

Frequently Asked Questions

Can I run JavaScript in a Puppeteer iframe?

Yes. Find the iframe’s Puppeteer Frame and call frame.evaluate(); the callback runs in that frame’s browser context.

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.

Does frame.evaluate() wait for a returned promise?

Yes. Puppeteer waits for the callback’s returned promise to resolve and returns its value, if serializable.

Which Puppeteer version is required?

The cited API references are labeled Puppeteer 25.10.0 through 25.12.0, but they do not establish a minimum version. Check the API reference for your installed version.

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 *

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

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. Shenzhen desk3 min
    HONOR Expands Beyond Smartphones With Humanoid Robot RevealHONOR said it unveiled its first humanoid robot at MWC 2026 and named shopping assistance, workplace inspections, and supportive companionship as intended uses. Later Robotics D1 claims and a reported…
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.