Recommended Free Tools
Puppeteer’s Page class is the per-tab API for navigating a browser page, finding and interacting with elements, running JavaScript in the page, waiting for outcomes, and capturing screenshots or PDFs. The examples below target the API reference version 25.12.0 surfaced in Puppeteer’s official documentation; check the matching docs if you use a different version.
What the Puppeteer Page API does
A Page represents one browser tab (or an extension background page). A browser can contain multiple Page instances. Use Page to coordinate work in a particular tab; use browser- or browser-context-level APIs when the operation applies beyond that tab. The Page class reference covers navigation, selection, evaluation, waiting, events and capture.
Common Page operations include goto(), goBack(), goForward() and reload() for navigation; $(), $$(), $eval() and $$eval() for DOM selection; and locator() for interactions. It also exposes methods such as evaluate(), waitForSelector(), screenshot() and pdf().
Set up a page and navigate
After installing Puppeteer in a Node.js project, create a browser, open a page and navigate to a URL. This example uses ES modules and assumes the project has Puppeteer installed.
#1 Best Overall
import puppeteer from 'puppeteer';
const browser = await puppeteer.launch();
try {
const page = await browser.newPage();
await page.goto('https://example.com');
console.log(await page.title());
} finally {
await browser.close();
}
goto() is the usual entry point for loading a URL. Other navigation methods are useful when your workflow needs to reload the current page or move through its history. A successful navigation does not by itself prove that an application-specific task has completed; wait for the element or state your task needs.
Choose an interaction method
Locators for synchronized interactions
Puppeteer’s interaction guide presents Locators as the higher-level way to express page interactions. Prefer them when their available methods fit the action you need, and consult the Page interactions guide for current syntax and behavior.
Rank #2
- HTML CSS Design and Build Web Sites
- Comes with secure packaging
- It can be a gift option
Selectors and element handles for lower-level control
When a Locator does not expose the capability you need, lower-level options such as page.waitForSelector() and ElementHandle remain available. Use $() to get the first matching element handle and $$() to get matching handles. $eval() calls a callback with the first matching element and throws if none exists; $$eval() calls its callback with all matching elements. They are not interchangeable if your selector may match zero or several elements.
const heading = await page.$eval('h1', element => element.textContent?.trim());
const links = await page.$$eval('a', elements =>
elements.map(element => element.href)
);
Run JavaScript in the page
page.evaluate(fn, ...args) executes a function in the page’s JavaScript context. Node.js variables are not automatically available inside that function: pass values explicitly as arguments. If the function returns a Promise, Puppeteer waits for it and returns the resolved value. Use evaluateHandle() instead when you need a handle to an object that remains in the page rather than an ordinary serialized result. See the evaluate() API reference.
Free tools Windows power users keep installed
One-click scans. No signup required.
Rank #3
const selector = 'h1';
const text = await page.evaluate((sel) => {
return document.querySelector(sel)?.textContent?.trim() ?? null;
}, selector);
Wait for the condition your task needs
Use the wait that describes the outcome you are testing, rather than inserting an arbitrary delay. Page-level options include waitForSelector() for an element, waitForFunction() for a truthy condition in the page, waitForRequest() or waitForResponse() for network events, and waitForNetworkIdle() for a network-idle condition.
Wait for an element
waitForSelector() resolves immediately if the selector already exists. It can also wait for an element to become visible or hidden. If the expected condition is not reached before the timeout, it throws. The documented default timeout is 30,000 ms; Page timeout settings can change the default. The method can operate across navigations. Consult the waitForSelector() reference for current options.
Rank #4
- Brand: Wiley
- Set of 2 Volumes
- A handy two-book set that uniquely combines related technologies Highly visual format and accessible language makes these books highly effective learning tools Perfect for beginning web designers and front-end developers
await page.waitForSelector('[data-testid="results"]', {
visible: true,
timeout: 10_000,
});
Coordinate an action that may navigate
If an action may trigger navigation, start the navigation wait at the same time as the action. This avoids the race in which the page navigates before the wait has been registered:
const [response] = await Promise.all([
page.waitForNavigation(),
page.click('a.some-link'),
]);
This is a synchronization pattern, not a claim that every click navigates. Adjust the selector and navigation wait options for the page. Navigation options document load as the default waitUntil event and 30 seconds as the default timeout; see the WaitForOptions reference. A lifecycle event can occur while an application is still rendering or fetching data, so follow it with a task-specific element, response or state wait when necessary.
Best Value
Capture screenshots and PDFs
page.screenshot() captures page imagery and returns image data, or a base64 string when requested. page.pdf() generates a PDF using print CSS media by default. To render the page with screen media instead, call page.emulateMediaType('screen') before generating the PDF. Capture output records what the browser rendered; it does not independently verify that the page’s data is correct.
await page.screenshot({ path: 'page.png', fullPage: true });
await page.pdf({ path: 'page.pdf', format: 'A4' });
await page.emulateMediaType('screen');
await page.pdf({ path: 'page-screen-media.pdf', format: 'A4' });
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Troubleshooting common Page API failures
A selector wait times out
- Cause: The selector is incorrect, the element never appears, or the expected element is not visible when visibility is required.
- Fix: Check the selector against the rendered page, wait for the actual task condition, and set an appropriate timeout. Use
waitForFunction()or a request/response wait if the outcome is not represented by an element.
$eval() throws
- Cause: No element matched the selector.
- Fix: Wait for the element first when it appears asynchronously, or use a selection approach that handles an absent match explicitly.
A click completes but the expected page has not loaded
- Cause: The navigation wait was attached after the action, or the click did not cause navigation at all.
- Fix: Register
waitForNavigation()and perform the click together withPromise.all(). If the action updates the page without navigation, wait for its resulting element, response or state instead.
evaluate() cannot see a Node.js variable
- Cause: The callback runs in the page context, not the Node.js lexical scope.
- Fix: Pass the value as an argument to
evaluate().
Or skip the browser setup
If you need a screenshot or PDF from a URL without managing a Puppeteer browser, ScreenshotNeo provides a website screenshot API and MCP server. One GET request returns a PNG, JPEG, WebP or PDF. For example, using cURL:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com -o shot.webp
See the ScreenshotNeo API documentation for request options. Cookie banners and consent interfaces, newsletter popups and chat widgets are handled before capture; each cleanup step can be turned off. Bot checks, blank pages, timeouts, failed loads and cache hits are not billed, and response headers report the page verdict and billing status. ScreenshotNeo also has an MCP server with take_screenshot, get_page_info and capture_pdf tools for AI agents. 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: 1,000 screenshots a month, no card required.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Frequently Asked Questions
Which Puppeteer version do these examples target?
They target the API reference version 25.12.0 surfaced in the official documentation. Check the docs matching the package version in your project.
Does waiting for navigation guarantee that an application has finished loading its data?
No. Navigation lifecycle events and application readiness are separate; wait for the specific element, response or state your task depends on.
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.

