ScreenshotNeo

BlogHow-to

How to Reload a Page with Puppeteer

Reload the current page with Puppeteer, choose the right wait condition, handle action-triggered reloads, and troubleshoot timeouts and stale content.

By the ScreenshotNeo team4 October 20267 min read

Use await page.reload() to reload the current page in Puppeteer. It returns a promise for the main-resource response, or null in cases where there is no response to return. By default, Puppeteer waits for the page’s load event, with a 30-second navigation timeout. A load event does not necessarily mean application-specific data has finished rendering, so wait for the element or state your next step needs.

const response = await page.reload();

1. Set up Puppeteer

This runnable example uses Node.js and Puppeteer. Install the package, save the code as reload.js, and run it with Node. Replace the example URL with the page you control or are authorized to automate.

npm install puppeteer
// reload.js
const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({ headless: true });
  try {
    const page = await browser.newPage();
    await page.goto('https://example.com');

    const response = await page.reload();
    console.log('Reload status:', response ? response.status() : 'no main-resource response');
    console.log('Current URL:', page.url());
  } finally {
    await browser.close();
  }
})().catch((error) => {
  console.error(error);
  process.exitCode = 1;
});

The call reloads the page’s current URL. If the response follows redirects, the reload promise resolves with the response for the final main resource. Check the response when its HTTP status matters; a resolved navigation promise alone does not guarantee a successful application state.

2. Choose when the reload is considered complete

page.reload(options) accepts reload options, including the navigation wait settings. The default waitUntil is 'load'; the default timeout is 30,000 milliseconds. Use the lifecycle milestone that fits the task:

Condition Use it when Trade-off
load You need the document and its dependent resources to reach the load event. This is the default. Pages with slow resources can take longer.
domcontentloaded You need the parsed document and do not need to wait for all resources. Images or other resources may still be loading.
networkidle0 You want to wait for network activity to become idle under Puppeteer’s lifecycle definition. Analytics, polling, streaming, or other persistent requests can prevent idleness.
networkidle2 You want a network-idle milestone that allows limited in-flight requests. It still may not match when an application has finished its own work.

These lifecycle events are documented by Puppeteer. An array means all listed events must occur before the wait succeeds. Do not choose network idle automatically: some sites keep requests open, while others render data after network activity has already settled.

const response = await page.reload({
  waitUntil: 'domcontentloaded',
  timeout: 60_000,
});

To require more than one lifecycle event:

await page.reload({
  waitUntil: ['domcontentloaded', 'load'],
  timeout: 45_000,
});

For application readiness, pair the reload with a targeted condition:

await page.reload({ waitUntil: 'domcontentloaded' });
await page.waitForSelector('[data-testid="results-ready"]', { timeout: 15_000 });

Replace the selector with a stable marker from the application. A selector wait is more meaningful than assuming a generic page lifecycle event means a client-rendered view is ready.

3. Wait for a reload triggered by a click or other action

If clicking a control causes the page to reload or navigate, start waiting for navigation before triggering the action. Run both promises together with Promise.all; otherwise, a fast navigation could finish before the waiter is registered.

const [response] = await Promise.all([
  page.waitForNavigation({ waitUntil: 'load', timeout: 30_000 }),
  page.click('button.reload-page'),
]);

console.log('Navigation status:', response ? response.status() : 'no main-resource response');

Use page.reload() when your script directly requests a reload. Use waitForNavigation() alongside the click when the action causes it. A navigation wait can also resolve for History API URL changes; in cases without a new main-resource response, its result is null.

If the action does not navigate and only updates content in place, do not wait for navigation. Instead, wait for the resulting selector or application state.

4. Set a navigation timeout

Set a timeout for one reload through its options, or change the page’s default navigation timeout for calls such as reload, goto, and waitForNavigation.

// Per reload
await page.reload({ timeout: 60_000 });

// For navigation waits on this page
page.setDefaultNavigationTimeout(60_000);
await page.reload();

The documented default is 30 seconds. A timeout of 0 disables the timeout; use that only when an unbounded wait is intentional. A bounded timeout makes a stalled navigation detectable and lets your code report or recover from it.

ReloadOptions also supports an optional AbortSignal. Use it when the caller needs to cancel a pending wait:

const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), 10_000);

try {
  await page.reload({ signal: controller.signal, timeout: 30_000 });
} finally {
  clearTimeout(timer);
}

An abort cancels the wait; it does not guarantee the remote server or all page activity has been stopped.

5. Reload without using the cache or service worker

A normal page.reload() does not itself promise a cache-free request or bypass a service worker. Configure those behaviors explicitly before reloading when you need to examine fresh network responses or exclude service-worker handling.

await page.setCacheEnabled(false);
await page.setBypassServiceWorker(true);
await page.reload();

These controls address different layers. Disabling the browser cache prevents cache use for requests; bypassing service workers prevents them from handling requests. Turn them on only when they match the behavior you need to investigate.

6. Troubleshoot common reload problems

Symptom Likely cause What to do
Navigation Timeout Exceeded The chosen lifecycle event did not occur before the configured timeout, or navigation is stalled. Choose a milestone that fits the task, inspect whether the page is still loading, and increase the timeout if the site legitimately needs longer. Keep the timeout bounded when possible.
The script continues, but the page still shows old or incomplete data The load event is not the application’s readiness signal; client-side rendering or data fetching continues afterward. After reload, wait for a specific selector or state that indicates the required data is ready.
A click-triggered reload is missed or the wait hangs The navigation waiter may have started after the click, or the click may update the page without navigating. Register waitForNavigation() in Promise.all with the click. If no navigation occurs, wait for the content change instead.
response is null The navigation did not produce a new main-resource response, such as a History API change or anchor-only navigation. Use the URL or page state to verify the outcome; do not assume a response object is always available.
Reload shows cached content during freshness testing Ordinary reload behavior does not disable the browser cache or bypass service workers. Set page.setCacheEnabled(false) and, if needed, page.setBypassServiceWorker(true) before reloading.
The wait fails immediately after cancellation An attached abort signal was triggered. Check who owns the signal and whether cancellation is expected; create a fresh controller for a later operation.
The response exists but the page is an error page The navigation completed at the HTTP level, but the server returned an unsuccessful status or the application rendered an error. Inspect response.status() and then check the page’s expected content or error state.

7. Performance, reliability, and cost considerations

  • Wait only for what you need. domcontentloaded can be an earlier milestone than load when dependent resources are irrelevant. A targeted selector wait avoids treating an unrelated resource as the task’s readiness condition.
  • Avoid unsuitable network-idle waits. Persistent requests can make them slow or impossible to reach. Prefer a page-specific readiness check when the application has a reliable marker.
  • Keep timeouts bounded. A deliberate upper limit helps automation report failures instead of tying up a browser process indefinitely.
  • Separate navigation success from task success. Inspect the response status when needed, and verify the expected page state before taking the next action.
  • Freshness changes can alter behavior. Disabling cache or bypassing a service worker is useful for particular debugging tasks, but does not represent the site’s normal visitor experience.
  • Account for browser operations in your own environment. This method runs a browser and makes page requests; resource use and any related infrastructure cost depend on your runtime and workload. No universal runtime or cost figure applies.

8. Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server. A single GET request returns a PNG, JPEG, WebP, or PDF. It is useful when the goal is to capture the page after it has loaded, rather than to interact with it in an existing Puppeteer session.

For an API key and the full parameter reference, see the ScreenshotNeo API documentation.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
    timeout=90,
)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
  • Cookie banners are accepted and removed before capture; known newsletter popups and chat widgets are removed too.
  • Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed. Response headers report the page verdict and billing status.
  • An MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients.
  • The free plan includes 1,000 screenshots a 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.

9. Frequently asked questions

Does page.reload() keep the current URL?

Yes. It reloads the page currently open in that Puppeteer page. Use page.goto(url) when you need to navigate to a different URL.

Can a reload response be null?

Yes. The return type is Promise<HTTPResponse | null>. Code that reads response fields should first check that a response exists.

Does waiting for load mean all app data is ready?

No. It means the load lifecycle event occurred. Wait for an application-specific element or state if your next step depends on client-rendered data.

Which approach should I use for a reload button?

Pair the click with waitForNavigation() in Promise.all if the button navigates. If it updates content in place, wait for that content to change instead.

Official Puppeteer references