The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Call await handle.jsonValue() to copy the serializable value of a Puppeteer JSHandle into Node.js. If you only need a property or computed result, use handle.evaluate() instead; if you need to keep working with an in-page object or DOM element, keep or create a handle with evaluateHandle().
Get the value with jsonValue()
jsonValue() returns a promise for a vanilla JavaScript value representing the serializable portions of the object referenced by the handle. For example:
As an Amazon Associate I earn from qualifying purchases.
const handle = await page.evaluateHandle(() => ({ name: 'Ada', active: true }));
try {
const value = await handle.jsonValue();
console.log(value); // { name: 'Ada', active: true }
} finally {
await handle.dispose();
}
The returned object is a Node.js-side value, not a live reference to the object in the page. Changes made to that Node.js object do not update the original page object. Puppeteer’s API reference describes the result as “A vanilla object representing the serializable portions of the referenced object.” Puppeteer JSHandle.jsonValue()
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Scan for outdated or missing drivers - takes under a minuteDriver Scan →Choose the right way to read the handle
| What you need | Use | Result |
|---|---|---|
| The handle’s serializable value | await handle.jsonValue() |
A Node.js-side value containing the serializable portions. |
| One property or a transformed value | await handle.evaluate(value => value.someProperty) |
The evaluation result, transferred back to Node.js. |
| A page-side object or DOM element to keep using | await page.evaluateHandle(() => ...) |
A handle to the page-side result; an element result is returned as an ElementHandle. |
| A value from a matching descendant of an element | await elementHandle.$eval(selector, node => node.textContent) |
The callback’s result for the first matching descendant. |
These operations serve different output needs: a serialized snapshot, selected data, or a continuing reference. See the official guides for JSHandle.evaluate(), Page.evaluateHandle(), and ElementHandle.$eval(). API details can vary by Puppeteer version; check the reference corresponding to the version installed in your project.
#1 Best Overall
Read a property or DOM text without converting the whole object
When the caller needs just one field, evaluate against the handle and return that field. Puppeteer passes the referenced object as the callback’s first argument:
const title = await handle.evaluate(value => value.title);
console.log(title);
You can also pass the handle to page.evaluate():
const title = await page.evaluate(value => value.title, handle);
console.log(title);
Evaluation can return a promise; Puppeteer waits for it and returns its resolved result. For an element, extract the property you want instead of returning the DOM node itself:
Rank #2
const heading = await page.$eval('h1', node => node.textContent?.trim() ?? '');
console.log(heading);
A DOM node returned from page.evaluate() does not become a useful Node.js DOM object; it may be reconstructed as {}. If you need to retain the element for further page-side work, use evaluateHandle() or a locator/element handle rather than trying to serialize the node. Puppeteer JavaScript execution guide
When to use evaluateHandle()
Use evaluateHandle() when the result should remain an object reference in the page—for example, when selecting an element to inspect in later operations. It awaits a returned promise and gives you a handle; if the result is an element, Puppeteer returns an ElementHandle. Call jsonValue() later only if you need a serializable snapshot of that referenced value.
Serialization limits and common errors
- Circular references:
jsonValue()can throw when the referenced object cannot be serialized because of circularity. Instead of serializing the whole object, useevaluate()to return a smaller, serializable object containing only the fields you need. toJSON()is not called: Do not expectjsonValue()to use an object’s customtoJSONmethod. If you need a particular representation, compute and return it withevaluate().- Unexpected empty object for a node: A DOM node is not a normal JSON data payload. Return its text, attributes, or other required fields from page context, or retain it with an element handle.
- Evaluation fails after navigation: A handle belongs to its page execution context. It is automatically disposed when its frame navigates away or its parent context is destroyed; reacquire the value or element after navigation.
- Handle-related errors later in a workflow: Check whether your code already disposed the handle or whether its frame/context was destroyed. Do not reuse a handle after disposal.
Dispose handles when you are finished
A handle keeps its referenced in-page object from being garbage-collected until it is disposed. Explicitly dispose handles that remain alive in your workflow once they are no longer needed. A try/finally block is useful when extraction might fail, as in the example above. Puppeteer also disposes handles automatically when the frame navigates away or the parent execution context is destroyed. Puppeteer JSHandle API
Or skip the browser setup
If your goal is to capture a page as an image or PDF rather than inspect a live DOM object, ScreenshotNeo provides a screenshot API and MCP server. One GET request returns a PNG, JPEG, WebP, or PDF; its screenshot options include full-page capture and element selection.
Rank #4
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. ScreenshotNeo accepts cookie/consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits cost nothing, and the response identifies the page verdict and billing status in headers. Its MCP server provides take_screenshot, get_page_info, and capture_pdf for AI agents. The Free plan includes 1,000 shots a month with no card; paid plans start at $5 for 3,000 shots. Learn about ScreenshotNeo or sign up for 1,000 free screenshots a month with no card.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Clear out junk files and repair common Windows errors3Fix the driver behind crashes, sound loss and screen glitchesFrequently Asked Questions
Does jsonValue() return a JSON string?
No. It resolves to a JavaScript value in Node.js. Use JSON.stringify() only if you specifically need text.
Can I call jsonValue() on an ElementHandle?
An ElementHandle is a kind of JSHandle, but a DOM node is usually better handled by reading specific properties or using element methods such as $eval().
Quick Recap
Best Value
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.




