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 glitchesUse page.goto(url) when you already know the destination. To click a link and wait for a document navigation, start page.waitForNavigation() and the click together with Promise.all so the wait is registered before navigation can happen. For client-side transitions, wait for the destination content your script actually needs.
Navigate directly when you know the destination URL
page.goto() is Puppeteer’s direct navigation method. Include the URL scheme, such as https://:
As an Amazon Associate I earn from qualifying purchases.
await page.goto('https://example.com');
The call resolves with the main resource response, or null in documented cases where a navigation-like change does not produce a new main-resource response. If you need to use the response, keep that distinction in mind:
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →const response = await page.goto('https://example.com');
if (response) {
console.log('Main resource status:', response.status());
} else {
console.log('No main-resource response was returned.');
}
For example, a History API URL change or an anchor navigation can count as navigation while returning null. A URL change alone therefore does not prove that the page has loaded the state your script needs.
#1 Best Overall
Click a link and wait for document navigation
For normal page interaction, Puppeteer recommends Locators. They wait for action preconditions such as visibility, enabled state, viewport placement, and a stable bounding box. Start the navigation wait and click concurrently:
const [response] = await Promise.all([
page.waitForNavigation(),
page.locator('a.my-link').click(),
]);
console.log(response ? response.status() : 'Navigation had no main-resource response');
Waiting only after the click can miss a fast navigation. Puppeteer’s Page.click API reference warns about this race and documents the concurrent pattern. The interaction guide identifies Locators as the recommended way to select and interact with elements.
Rank #2
Choose a selector that identifies the intended link
CSS selectors work by default. Puppeteer also supports text, accessibility-role/name, XPath, and open Shadow DOM selector options. Prefer a selector tied to the intended link, and refine it if the page has repeated matches; an ambiguous selector can target the wrong element.
PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Outdated 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 matchHandle client-side transitions by waiting for the destination state
Single-page applications may update the URL and content without loading a new document. In that case, navigation waiting may resolve with null. Wait for a site-specific element that demonstrates the state your script needs, such as the destination heading:
const [response] = await Promise.all([
page.waitForNavigation(),
page.locator('a.my-link').click(),
]);
await page.locator('h1.destination-title').wait();
console.log('Destination content is ready');
Replace h1.destination-title with a selector from the actual destination page. Do not treat it as a universal selector. If the application transition does not trigger navigation at all, omit waitForNavigation() and wait directly for the destination element after clicking:
await page.locator('button.open-destination').click();
await page.locator('h1.destination-title').wait();
The exact readiness condition depends on what the rest of your automation will do. A visible heading may be enough to read a page title; a later task that interacts with a form should wait for the relevant form control instead.
Rank #4
Use waitForSelector when you need a lower-level DOM wait
page.waitForSelector() remains available when you specifically need to wait for DOM presence, visibility, or a hidden state. It accepts a timeout and returns an ElementHandle, or null in the documented hidden case. Unlike Locator actions, it does not provide automatic action retry.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
const handle = await page.waitForSelector('.destination-title', {
visible: true,
timeout: 10_000,
});
if (!handle) {
throw new Error('Destination title did not become visible');
}
try {
console.log(await handle.evaluate(element => element.textContent));
} finally {
await handle.dispose();
}
Dispose of an ElementHandle when you no longer need it. For a straightforward click, prefer a Locator; use the lower-level handle approach when its explicit DOM-wait behavior is useful. See Puppeteer’s interaction guide and waitForSelector API reference.
Best Value
- Used Book in Good Condition
Minimal end-to-end flow
A complete browser workflow consists of launching Puppeteer, opening a page, navigating to a starting URL, clicking the link, and checking the resulting page. The following example assumes Puppeteer is installed in the project and the target page contains the example link and destination heading:
const browser = await puppeteer.launch();
try {
const page = await browser.newPage();
await page.goto('https://example.com');
const [response] = await Promise.all([
page.waitForNavigation(),
page.locator('a.my-link').click(),
]);
await page.locator('h1.destination-title').wait();
console.log('URL:', page.url());
console.log('Main response:', response ? response.status() : 'none');
} finally {
await browser.close();
}
For your own page, replace the URL and selectors with real values. The Puppeteer getting-started guide demonstrates the basic launch, page creation, navigation, and page inspection sequence.
Troubleshooting clicks and navigation waits
- The wait hangs or times out: Check that the click actually triggers a document navigation. For a client-side transition, wait for the destination state instead of requiring a main-resource response.
- The navigation happened, but the response is null: This can occur with History API or anchor navigation. Check the resulting URL and wait for the relevant destination content.
- The click fails because the element is not ready: Confirm the selector matches the intended element and that the element is available on the current page. Locators wait for action preconditions and retry when an action cannot yet be performed.
- The script clicked the wrong link: Refine the selector to distinguish repeated matches, or select by an appropriate text or accessibility role/name.
- A selector wait succeeds but a later interaction fails: Presence in the DOM is not necessarily readiness for interaction. Use a Locator action for routine interaction, or wait for the precise visible state the next step requires.
- The URL changed but the page is not ready for the next step: Wait for an application-specific element or state, not just a URL change.
Version and API considerations
Puppeteer documentation pages consulted for this workflow identify version 25.12.0 for the interaction guide and key Page API references; a Frame navigation reference appears at 25.9.0. Check the API documentation matching the Puppeteer version installed in your project before depending on version-specific options.
Or skip the browser setup
If your goal is a screenshot rather than an interactive browser journey, ScreenshotNeo can return an image or PDF with one GET request. See the API documentation for available parameters.
Quick Recap
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
ScreenshotNeo removes cookie banners, popups, and chat widgets before capture; bot checks, blank pages, and failed loads are never billed. Its 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 free.
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.




