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 →Use page.goto(url) when you already know the destination. When a link click should navigate to another document, start page.waitForNavigation() and the click together with Promise.all so the wait is registered before navigation begins. For client-side transitions, wait for the destination content your script actually needs; a URL change may not produce a document response.
Navigate directly when you know the destination URL
page.goto() is Puppeteer’s direct navigation API. Include the URL scheme, such as https://:
await page.goto('https://example.com');
In a complete script, first launch a browser and create a page, then navigate. This example uses Puppeteer’s documented launch-and-page flow:
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
try {
const page = await browser.newPage();
const response = await page.goto('https://example.com');
console.log('HTTP status:', response?.status() ?? 'no main-resource response');
console.log('Final URL:', page.url());
} finally {
await browser.close();
}
})();
goto() resolves with the main resource’s response, or null in documented cases. A null response does not necessarily mean the page failed: some navigation-like changes do not fetch a new main document.
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →#1 Best Overall
Click a link and wait for document navigation
For routine element interaction, Puppeteer recommends Locators. They wait for action preconditions such as visibility, enabled state, viewport placement, and a stable bounding box. If the click is expected to load another document, register the navigation wait and click concurrently:
const [response] = await Promise.all([
page.waitForNavigation(),
page.locator('a.my-link').click(),
]);
console.log('Destination URL:', page.url());
console.log('HTTP status:', response?.status() ?? 'no main-resource response');
This order matters. If the click happens before waitForNavigation() is registered, navigation may start first and the wait can miss it. Puppeteer’s Page.click API reference documents the race and the same Promise.all pattern using page.click(selector).
Rank #2
Choose a selector that identifies the intended link
CSS selectors work by default. Puppeteer also supports text, accessibility role and name, XPath, and open Shadow DOM selector options. Prefer a selector tied to the link’s meaningful role or context, and refine it when the page contains multiple matches; an ambiguous selector can click the wrong link.
Handle client-side transitions by waiting for destination state
Single-page applications may update the URL through the History API or navigate to an anchor without loading a new document. waitForNavigation() treats these as navigation, but its result may be null because there is no new main-resource response. Do not use a non-null response as the only proof that the transition succeeded.
Recommended Free Tools
Instead, wait for an element that represents the state your script needs. Pick a selector from the actual destination page; there is no universal heading or content selector that works across sites:
await page.locator('a.my-link').click();
await page.locator('[data-testid="destination-ready"]').wait();
console.log('Destination URL:', page.url());
Replace [data-testid="destination-ready"] with a selector present when the target view is ready. The official Page.waitForNavigation API reference describes the response behavior for History API and anchor changes.
Rank #4
Use waitForSelector when you need a lower-level DOM wait
page.waitForSelector() is still available when you specifically need to wait for DOM presence, visibility, or a hidden state. It supports a timeout and returns an ElementHandle, or null in the documented hidden case. Unlike Locators, it does not provide Locator-style automatic action retries. Dispose of returned handles when you no longer need them.
const handle = await page.waitForSelector('.result', { visible: true });
if (!handle) {
throw new Error('Expected visible result was not found');
}
try {
console.log(await handle.evaluate(element => element.textContent));
} finally {
await handle.dispose();
}
For normal click-and-interact work, the Page interactions guide recommends Locators; choose the lower-level wait when its explicit DOM wait or handle is useful.
Best Value
- Used Book in Good Condition
Troubleshoot missed clicks and waits
- The navigation wait times out: the click may cause a client-side transition rather than a document load. Wait for a destination-specific element or state instead of requiring a main-resource response.
- The wait resolves but response is null: a History API or anchor change can count as navigation without a new main-resource response. Check
page.url()and the destination content. - The script clicks the wrong link: the selector may match multiple elements. Narrow it using page context, link text, or an accessible role and name.
- The click cannot proceed because the element is not ready: Locators check action preconditions and retry as needed. Verify that the selector identifies a real, enabled element in the intended view.
- A handle-based flow retains stale elements: a DOM change can make an earlier handle unsuitable. Locate the element again after the transition, and dispose handles when finished.
Or skip the browser setup
If you need a screenshot rather than browser interaction, ScreenshotNeo provides a website screenshot API and MCP server. One GET request can return an image or PDF; it does not click through page flows.
Quick Recap
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. It removes cookie banners, newsletter popups, and chat widgets before capture; bot checks, blank pages, and failed loads are not billed. Its MCP server lets AI agents take screenshots. The free plan includes 1,000 screenshots per month without a card; paid plans start at $5 for 3,000. Sign up for free and get 1,000 screenshots a month with no card.
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.

