October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsWindows FixRecommendedWindows errors stealing your time? Find the fix fastScan stability, cleanup and performance issues.Fix NowOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk4 min

How to Evaluate JavaScript on a Puppeteer Page

A practical guide to executing browser-side JavaScript with Puppeteer, passing arguments, returning values, keeping DOM handles, and avoiding common evaluation errors.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use await page.evaluate(() => ...) to run JavaScript in the browser page and return a value to your Puppeteer script. The callback runs in the page’s context, not Node.js: pass any Node-side data as arguments rather than trying to reference it from inside the callback.

Run JavaScript in the page context

page.evaluate(pageFunction, ...args) runs the supplied function in the page and returns its result to your script. Prefer a function over a string: Puppeteer’s API documentation says functions are easier to debug and work better with TypeScript. The callback’s result is serialized for transfer back to Node.js.

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

The code inside the callback can use browser-page objects such as document. It cannot use variables or helper functions that exist only in the surrounding Node.js script.

Pass Node.js values into the callback

Supply values after the callback. Puppeteer passes them as positional arguments to the function running in the page.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
const suffix = ' — checked';
const label = await page.evaluate(
  pageSuffix => `${document.title}${pageSuffix}`,
  suffix,
);
console.log(label);

Name the callback parameter explicitly; it receives the value, not the Node-side variable’s lexical scope. Define any helper logic the page needs inside the callback, or pass the necessary data as arguments. A JSHandle can also be supplied as an argument when you need to use an object already obtained from the page.

Handle asynchronous page work

Await the Puppeteer call in Node.js. If the page function returns a Promise, Puppeteer waits for it to resolve and returns its resolved value.

const readyState = await page.evaluate(async () => {
  await new Promise(resolve => setTimeout(resolve, 100));
  return document.readyState;
});
console.log(readyState);

This only waits for the Promise your callback returns. A delay does not guarantee that an application-specific condition has been met. When you need a particular element or state to appear, use an appropriate Puppeteer wait strategy before evaluating it.

Choose the right evaluation method

Need Method What it returns or does
Read or compute a value in the current page page.evaluate() Returns the serialized result; waits for a returned Promise to resolve.
Keep a page object or DOM node for later operations page.evaluateHandle() Returns a JSHandle; a referenced element is represented by an ElementHandle.
Run a callback on the first element matching a selector page.$eval() Passes the matched element as the callback’s first argument. Throws if no element matches.
Install setup code before page scripts page.evaluateOnNewDocument() Runs after a new document is created and before its scripts execute.

These methods differ by what they target, when they run, and whether you get a serialized value or a live in-page reference.

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

Use evaluateHandle for a reference

A normal evaluation does not give Node.js a live DOM object. For example, returning document.body through evaluate serializes the result rather than transferring a usable browser DOM node. Use a handle when you need to keep and operate on the page object.

const body = await page.evaluateHandle(() => document.body);
const html = await body.evaluate(element => element.innerHTML);
console.log(html);
await body.dispose();

Handles retain references to in-page objects. Dispose of them when you are finished, unless navigation or execution-context destruction has already disposed of them.

Use $eval for one selector match

$eval finds the first matching element and supplies it to your callback:

const text = await page.$eval('h1', element => element.textContent);
console.log(text);

If the selector does not match, $eval throws. If the element may appear later, wait for it or use a suitable locator or wait strategy before reading it.

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

Use evaluateOnNewDocument for early setup

When code must run before a site’s own scripts, register it before navigating to the page:

await page.evaluateOnNewDocument(() => {
  // Runs in the new document before its scripts execute.
});

This setup runs on navigation and also applies to qualifying child-frame attachment or navigation events. It is different from evaluate, which executes against the current document.

Common errors and fixes

  • “My Node variable is undefined.” The callback cannot close over Node.js scope. Pass the value as an argument to evaluate.
  • “I got an empty-looking object instead of a DOM element.” Evaluation serializes its result. Use evaluateHandle if you need an in-page reference.
  • “The result is a Promise or arrives too early.” Await the outer page.evaluate call. If the callback returns a Promise, Puppeteer awaits its resolution; separately wait for any page condition your task requires.
  • “$eval throws.” The selector may not match an element yet, or at all. Confirm the selector and wait for the element when it is expected to load later.
  • “Memory or handle count grows during a long run.” Dispose of handles you no longer need with dispose().
  • “TypeScript accepts code that fails in the page.” Node-side types do not establish which browser globals exist at runtime. Check that the evaluated function uses APIs available in the browser page.

Or skip the browser setup

If your goal is a screenshot rather than custom page-side computation, ScreenshotNeo can capture a URL with one request. For example, using cURL:

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. Cookie and consent banners, newsletter popups, and chat widgets are removed before capture; bot checks, blank pages, and failed loads are not billed. An MCP server lets AI agents take screenshots, and the free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. Sign up for the free plan.

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.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Frequently Asked Questions

Can page.evaluate() return a Promise?

Yes. Puppeteer waits for the returned Promise to resolve and passes its resolved value back to Node.js.

Can I return a DOM element with page.evaluate()?

The result is serialized, not transferred as a live Node.js DOM object. Use page.evaluateHandle() when you need the page object by reference.

Which Puppeteer version are these API names based on?

The official API references reviewed on October 3, 2026 list evaluate, $eval, and evaluateHandle at version 25.12.0; JSHandle at 25.9.0; and evaluateOnNewDocument at 25.11.0. The JavaScript execution guide is labeled Next, so check the versioned API for the Puppeteer release you have installed.

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.

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

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. 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
PC Slower Than It Used to Be?Free scan - under a minute
Outdated Drivers Are Slowing You DownFree scan - exact matches

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.