Use page.waitForSelector(selector, options) to wait for an element to appear, become visible, disappear, or become hidden. The main options are visible, hidden, timeout, and signal. In Puppeteer’s version 25.12.0 reference, the default timeout is 30 seconds; a selector that already exists when the call begins is returned immediately.
What waitForSelector waits for
waitForSelector() takes a selector and an optional options object. The selector can be CSS or Puppeteer selector syntax. It returns a promise for an ElementHandle matching the selector. If there is no match yet, Puppeteer waits; if the timeout expires, the promise throws. If a match already exists when the method is called, it returns immediately. See the Puppeteer Page.waitForSelector() reference.
As an Amazon Associate I earn from qualifying purchases.
By default, the method waits for a matching element to exist, without requiring it to be visible. That distinction matters: a matching element can be in the DOM while hidden by CSS.
Recommended Free Tools
Configure the options
| Option | What it does | Default and practical use |
|---|---|---|
visible |
When true, waits for a matching element to exist and be visible. Puppeteer documents visibility in terms of the element not having display: none or visibility: hidden. |
false. Set it to true when the next step requires the element to be visible. |
hidden |
When true, waits until the selector is absent from the DOM or the matching element is hidden. An absent selector satisfies this condition, and the promise resolves to null. |
false. Useful for waiting for a loading indicator to disappear. |
timeout |
Maximum wait, in milliseconds. | 30,000 milliseconds (30 seconds). Use a per-call value for a particular wait; set 0 to disable the timeout. |
signal |
An AbortSignal that cancels the wait. |
No signal is required. Supply one when the surrounding task needs to stop waiting early. |
These option definitions and defaults are documented in Puppeteer’s WaitForSelectorOptions reference and method reference (version 25.12.0).
#1 Best Overall
Common configurations
Wait for an element to exist
const element = await page.waitForSelector('img');
This uses the default visible: false: it waits for a match, not specifically for visibility. If the matching element is already present, the call can resolve immediately.
Wait for an element to be visible
const image = await page.waitForSelector('img', {
visible: true,
timeout: 10_000,
});
The 10-second limit is an example per-call setting, not Puppeteer’s default. Visibility here means the documented CSS checks; it does not establish that an element is unobstructed or that a person could successfully interact with it.
Rank #2
Wait for a loading element to disappear
const loadingIndicator = await page.waitForSelector('.loading', {
hidden: true,
timeout: 15_000,
});
This resolves when .loading is either absent or hidden under Puppeteer’s documented CSS definition. If it is absent, the result is null, so do not assume this result is always an element handle.
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Fix the driver behind crashes, sound loss and screen glitches3Clear out junk files and repair common Windows errorsUse a page-wide default timeout
page.setDefaultTimeout(15_000);
const result = await page.waitForSelector('#results');
Page.setDefaultTimeout() changes the page’s default timeout. Use the per-call timeout option when only one wait needs a different limit. A timeout of 0 disables the limit; use it only if an unbounded wait is intentional, since a selector that never satisfies the condition can leave the task waiting indefinitely.
Rank #3
Cancel a wait with an AbortSignal
const controller = new AbortController();
const pending = page.waitForSelector('#results', {
timeout: 20_000,
signal: controller.signal,
});
// Call this when the surrounding operation should stop waiting:
controller.abort();
try {
const element = await pending;
// Use element if the wait completed before cancellation.
} catch (error) {
// Handle the rejected wait, including cancellation or timeout.
}
The API accepts an AbortSignal for cancellation. Handle a rejected promise in the same way you handle other failed waits; do not treat cancellation as a successful element match.
Use the returned handle safely
The result for a successful match is an ElementHandle. Puppeteer’s interactions guide demonstrates disposing of a handle after use. For example:
const element = await page.waitForSelector('div > .class-name');
try {
// Use element here.
} finally {
if (element) await element.dispose();
}
The null check is useful when using hidden: true, because an absent selector resolves to null. The guide describes waitForSelector() as a lower-level API and notes that some page-level APIs, including page.click(selector), use it for backwards compatibility. See Puppeteer’s page interactions guide.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
When to use a locator instead
Choose waitForSelector() when you need to wait for a selector condition and work directly with the resulting handle. For an interaction such as clicking, Puppeteer’s guide presents locators as a higher-level workflow: they wait for relevant action preconditions, such as visibility and enabled state, and inherit the page timeout by default. These workflows are not interchangeable in every case; choose based on whether you need a selector match or an action with its preconditions handled.
Best Value
Troubleshoot waits that fail or stall
- The wait times out. Check that the selector matches the page’s actual markup and that the page reaches the state you expect before the limit expires. Increase the per-call timeout only when the operation reasonably needs longer; use
Page.setDefaultTimeout()if the page-wide default is inappropriate. - The call resolves, but the element is not visible. The default does not require visibility. Set
visible: trueif the documented visibility condition is what you need. - The hidden wait resolves with
null. This is expected when the selector is absent from the DOM. The hidden condition is satisfied by either absence or CSS-hidden state. - The wait appears to hang. Check whether you set
timeout: 0, which disables the timeout, or whether a longer page default is in effect. Use a finite timeout unless waiting without a limit is deliberate. - The wait ends before your work is finished. An
AbortSignalcancels the wait; check whether the surrounding code aborts its controller before the selector condition is met. - You need to click or otherwise interact. Consider a locator workflow for an action whose preconditions matter, rather than treating a selector match alone as proof that interaction is ready.
Or skip the browser setup
If your goal is a website screenshot rather than browser automation, ScreenshotNeo returns an image or PDF from one GET request. Its API call can capture a page without setting up a Puppeteer browser session:
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. Before a capture, ScreenshotNeo accepts cookie or consent banners as a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each step can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing status. Its MCP server offers take_screenshot, get_page_info, and capture_pdf tools for AI agents 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.
Free tools Windows power users keep installed
One-click scans. No signup required.
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.




