How to Add a Delay Before Taking a Screenshot in Puppeteer
Pause before a Puppeteer screenshot with a timer, or wait for a selector or app-ready condition when elapsed time alone cannot confirm the page is ready.
To pause for a fixed time before a Puppeteer screenshot, await a JavaScript timer immediately before page.screenshot():
await new Promise(resolve => setTimeout(resolve, 2000));
await page.screenshot({ path: 'screenshot.png' });
The delay is in milliseconds, so 2000 means two seconds. Puppeteer’s screenshot options control the capture; they do not provide a delay option. Put timing or readiness logic in your script before the capture call. See the official Page.screenshot() API and ScreenshotOptions reference.
1. Add a fixed delay after navigation
This runnable example opens a page, waits two seconds, and writes a screenshot. It assumes Puppeteer is installed in the project and Chromium is available through Puppeteer.
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
try {
const page = await browser.newPage();
await page.goto('https://example.com');
await new Promise(resolve => setTimeout(resolve, 2000));
await page.screenshot({ path: 'screenshot.png' });
} finally {
await browser.close();
}
})();
page.screenshot() returns a promise. Await it so the write completes before your script closes the browser or continues to use the result. The timer only guarantees that the specified time passed; it does not guarantee that network requests, animations, or application rendering finished.
2. Choose a wait that matches what must be ready
A timer is appropriate when you specifically need a pause, such as allowing a brief transition to finish. If the actual requirement is “capture when this content is ready,” wait for that condition instead.
Wait for a selector
await page.waitForSelector('#content-ready', { visible: true });
await page.screenshot({ path: 'screenshot.png' });
waitForSelector() waits for the selector to appear. With visible: true, Puppeteer also requires that it not be hidden with display: none or visibility: hidden. If the selector is already present, the wait can return immediately. See the waitForSelector() API.
Wait for application state
If your app exposes a readiness flag, use waitForFunction() to wait for it to become truthy:
await page.waitForFunction(() => window.appReady === true);
await page.screenshot({ path: 'screenshot.png' });
This is more direct than guessing a duration when the application can tell the browser that its data or rendering is ready. The condition may also be asynchronous. See the waitForFunction() API.
Wait for navigation or network settling
Puppeteer’s screenshots guide shows using a navigation lifecycle condition before capture, for example:
await page.goto('https://example.com', { waitUntil: 'networkidle2' });
await page.screenshot({ path: 'screenshot.png' });
This waits for the selected navigation condition; it does not prove that every app-specific render or animation has finished. A selector or explicit app-ready condition can be a better signal when the page has a known readiness marker. See the official Puppeteer Screenshots guide.
3. Combine a readiness condition with a short settling pause
Sometimes the page reaches a useful state and then needs a short, known transition interval. Wait for the signal first, then add the timer:
await page.waitForSelector('#content-ready', { visible: true });
await new Promise(resolve => setTimeout(resolve, 300));
await page.screenshot({ path: 'screenshot.png' });
Keep this pause only if the page needs it. A fixed interval adds that time to every capture, even when the page becomes ready sooner.
4. Screenshot options are separate from delay
Timing belongs before the call. The screenshot options configure the output and capture area, not when to start capturing.
| Option | What it controls |
|---|---|
path |
Where Puppeteer writes the screenshot file. |
fullPage |
Whether to capture the full page rather than only the viewport. |
clip |
A specific capture rectangle. |
encoding |
Whether the result is returned as a buffer or encoded string. |
quality |
Image quality for supported formats. |
Check the ScreenshotOptions reference for the options supported by your installed Puppeteer version. None substitutes for an awaited timer or readiness condition.
5. Timeouts and failure handling
Selector and function waits can time out if their condition never becomes true. The documented default for applicable wait APIs is 30 seconds; timeout: 0 disables the timeout. Disabling it can leave a script waiting indefinitely if the condition is broken. See WaitTimeoutOptions.
await page.waitForSelector('#content-ready', {
visible: true,
timeout: 10000
});
await page.screenshot({ path: 'screenshot.png' });
Choose a timeout that fits your page and environment, and handle a timeout at the job boundary so one page does not silently stall a larger capture process. Do not treat a timeout as proof that the page is ready.
6. Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| The screenshot still shows a loading state after the delay. | The page takes longer than the fixed interval, or rendering is driven by a later request or app state. | Wait for a visible content selector or an application readiness condition. Increase the timer only when a fixed settling interval is actually the requirement. |
waitForSelector() times out. |
The selector is wrong, the content never appears, or it remains hidden. | Check the selector and page state; use visible: true only when visibility is required. Set an intentional timeout and handle the failure. |
| The screenshot is not written before the script exits. | The screenshot promise was not awaited, or the browser was closed before it completed. | Use await page.screenshot(...) and close the browser afterward, preferably in a finally block. |
| A network-idle wait completes but the page is still visually incomplete. | Network settling is not the same as application readiness; content may render later or animate. | Wait for the app’s specific selector or state, optionally followed by a short settling pause. |
| Captures are consistently slower than needed. | A long fixed delay is paid on every run, including pages that become ready sooner. | Use the earliest reliable selector or state condition instead of a conservative fixed wait. |
7. Performance, reliability, and cost
A fixed delay is simple and predictable, but it adds its full duration to every screenshot. At scale, a long delay reduces throughput and keeps browser pages and processes occupied. Readiness-based waits can finish sooner when the page is ready early, while still waiting longer when it is not. Give condition waits bounded timeouts and make failures visible to the caller so stalled pages do not consume resources indefinitely.
The timer itself does not make capture more reliable; it only changes when capture starts. Reliability comes from waiting for a condition that represents the content you need and handling cases where that condition never occurs. Puppeteer’s screenshot API has no separate delay charge or option; your operational cost depends on the runtime and infrastructure you use.
8. Or skip the browser setup
If you need a screenshot without managing Puppeteer and a browser, ScreenshotNeo provides a website screenshot API and MCP server. One GET request can return an image or PDF. This example captures a page as WebP; replace the target URL and use your API key:
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 documentation for request parameters. Cookie banners are accepted and removed, along with known newsletter popups and chat widgets, before the shot; each step can be turned off. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and response headers identify the page verdict and billing status. Its MCP server lets AI agents use take_screenshot, get_page_info, and capture_pdf. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000.
Sign up free for 1,000 screenshots a month with no card.
9. FAQ
Does Puppeteer have a screenshot delay parameter?
The documented screenshot options do not include one. Await a timer or readiness condition before calling page.screenshot().
Is two seconds the right delay?
Only if two seconds matches your page’s needs. Use a selector or app condition when you need a specific state rather than a particular elapsed time.
Does waiting for a selector mean all images and animations are finished?
No. It confirms the selector condition, not every visual detail on the page. Add the specific conditions your screenshot depends on.
Can the timer be zero?
Yes, but it adds no meaningful pause. If the capture must follow a condition, await that condition directly.


