Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallUse page.evaluate(fn, ...args) to run a function in the current page, page.evaluateOnNewDocument(fn, ...args) to install setup before scripts run in new documents, and page.exposeFunction(name, fn) when page JavaScript needs to call back into Node.js. These APIs cross execution contexts: pass browser callbacks the values they need instead of expecting them to see Node.js variables.
Run a function in the current page with page.evaluate()
Puppeteer’s Page.evaluate() API evaluates a function in the page’s context and returns its result. Pass any inputs after the callback. If the callback returns a Promise, Puppeteer waits for it to resolve.
As an Amazon Associate I earn from qualifying purchases.
const result = await page.evaluate((selector) => {
return document.querySelector(selector)?.textContent?.trim() ?? null;
}, '#headline');
The callback runs in the browser, not in the Node.js process. It cannot automatically read variables from the surrounding Node.js lexical scope. Supply those values as arguments:
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →const prefix = 'Result: ';
const result = await page.evaluate((selector, prefix) => {
return prefix + (document.querySelector(selector)?.textContent ?? '');
}, '#headline', prefix);
Keep the callback self-contained with respect to browser APIs and pass data across the boundary explicitly. This makes it clear which values the page-side function receives.
Choose the API by timing and call direction
| Need | API | Behavior |
|---|---|---|
| Run work now in the current page | page.evaluate(fn, ...args) |
Runs in the page context; Puppeteer waits for a returned Promise to resolve. Puppeteer API |
| Install code before page scripts in new documents | page.evaluateOnNewDocument(fn, ...args) |
Runs after document creation and before page scripts. It also runs on navigation and in child frames when they attach or navigate. Puppeteer API |
| Let browser JavaScript call Node.js | page.exposeFunction(name, fn) |
Adds a function on window; its result is returned through a Promise, and the exposed function survives navigation. Puppeteer API |
Install code before the page loads
Register evaluateOnNewDocument() before navigating if the code must affect that navigation. It is a lifecycle hook for new documents, not a way to retroactively alter a document that has already loaded.
await page.evaluateOnNewDocument((language) => {
Object.defineProperty(navigator, 'language', { get: () => language });
}, 'en-US');
await page.goto(url);
The callback runs after the document is created but before its scripts execute. The supplied argument is available to the callback in the page context.
Rank #2
Let page code call a Node.js function
Use exposeFunction() when the direction of the call is from page JavaScript to Node.js. The exposed callback itself is implemented in Node; it is not serialized into the page.
await page.exposeFunction('lookupRecord', async (id) => {
return await getRecordFromNode(id);
});
const record = await page.evaluate(() => window.lookupRecord('item-42'));
Here, getRecordFromNode belongs to the Node.js process. Page code invokes the exposed window.lookupRecord, and the returned value can be awaited in the page.
Pass functions and arguments, not generated source strings
Puppeteer serializes function callbacks using Function.prototype.toString(). Its troubleshooting guidance warns that transpilers can change generated function output in ways that are incompatible with evaluation. That is a compatibility risk, not evidence that every transpiler fails.
For ordinary evaluation, prefer a callback plus explicit arguments to assembling source text. This avoids hand-interpolating data into code and makes the context boundary visible. If a transpiled callback fails, inspect the function form Puppeteer receives and try a simple, untransformed callback to isolate serialization as the cause.
Rank #4
Troubleshoot “Cannot evaluate a string with arguments”
This error means arguments are being supplied with source text rather than a function callback. Arguments belong to a function passed to evaluation; they are not automatically substituted into a string of JavaScript source. Use this pattern:
const value = await page.evaluate((name) => {
return document.querySelector(name)?.textContent ?? null;
}, '#headline');
If the callback needs a Node.js value, pass it as an argument rather than referring to the outer variable from inside the callback.
Best Value
When Content Security Policy is involved
Evaluation is the normal way to run a callback in page context; do not start by bypassing a site’s Content Security Policy. If your use case specifically requires a CSP bypass, Puppeteer’s Page documentation for setBypassCSP() says bypassing takes effect at CSP initialization. Set it before navigating to the domain, rather than after the page has loaded.
Or skip the browser setup
If the task is to capture a website rather than run custom Puppeteer logic, ScreenshotNeo offers a website screenshot API and MCP server for developers. A one-call request returns a screenshot or PDF; use the ScreenshotNeo API documentation for request options.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
- Cookie banners are accepted and removed, along with known consent platforms, newsletter popups and chat widgets, before the shot; each step can be turned off.
- Bot checks, blank pages, timeouts, failed loads and cache hits are not billed. The response identifies page verdict and billing status in headers.
- An MCP server provides
take_screenshot,get_page_infoandcapture_pdftools for Claude, Cursor and other MCP clients. - The Free plan includes 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 screenshots.
Sign up for ScreenshotNeo’s free plan to get 1,000 screenshots a month with no card.
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.




