Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

To download a page whose content appears after JavaScript runs, use a real browser rather than a basic HTTP client. Launch Playwright or Puppeteer, navigate to the page, wait for a page-specific readiness signal, and then save the result as a downloaded file, rendered HTML, or PDF. The correct workflow depends on which artifact you need.

Why ordinary downloads miss JavaScript content

An HTTP client such as curl receives the server’s initial response. It does not execute the JavaScript that builds a product list, loads an API response, opens a modal, or replaces a loading shell with final content. Saving that response can therefore produce incomplete HTML.

A browser automation library runs the page like a user: it evaluates scripts, performs network requests, maintains cookies, and exposes the updated DOM. Use a browser when the required data is rendered client-side, when a button creates a file, or when you need a visual PDF.

  • Exact file after a click: listen for the browser’s download event and save the resulting attachment.
  • Post-JavaScript markup: wait until the application is ready, then write the browser’s current HTML.
  • Shareable document: generate a PDF after choosing print or screen media.

Choose the artifact before writing code

Goal Recommended method Important detail
Save a file produced by a button Playwright download event Start waiting before clicking, then call saveAs().
Save the rendered DOM Puppeteer page.content() or the equivalent Playwright method The result includes current markup, not a complete offline archive.
Create a PDF Puppeteer page.pdf() or Playwright PDF support Print CSS is the default; emulate screen media when needed.

Prerequisites and browser installation

Use a current Node.js project and install one browser automation library. Playwright’s installation workflow includes browser binaries and, on some operating systems, required system dependencies. Puppeteer normally downloads a compatible Chrome during installation; package managers or security policies that block install scripts can prevent that download, so install the required browser explicitly if launch fails.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
#1 Best Overall
Sale
Seagate 2TB Portable Hard Drive | USB 3.0 (STGX2000400)
  • Easily store and access 2TB to content on the go with the Seagate Portable Drive, a USB external hard drive
  • Designed to work with Windows or Mac computers, this external hard drive makes backup a snap just drag and drop
  • To get set up, connect the portable hard drive to a computer for automatic recognition no software required
  • This USB drive provides plug and play simplicity with the included 18 inch USB 3.0 cable
  • The available storage capacity may vary.

For Playwright, a typical setup is:

npm init -y
npm install playwright
npx playwright install

For Puppeteer:

npm init -y
npm install puppeteer

Run these commands in an environment where browser processes are permitted. In containers, you may also need the operating-system packages documented by your chosen library.

Download a file created by a JavaScript click with Playwright

Playwright’s Download API emits its download event once the download starts. Register the wait before the click; registering afterward can miss a fast download.

import { chromium } from 'playwright';

const browser = await chromium.launch();
const page = await browser.newPage({ acceptDownloads: true });

try {
  await page.goto('https://example.com/export', { waitUntil: 'domcontentloaded' });
  await page.getByText('Download file').waitFor();

  const downloadPromise = page.waitForEvent('download');
  await page.getByText('Download file').click();
  const download = await downloadPromise;

  await download.saveAs('/tmp/' + download.suggestedFilename());
  console.log('Saved:', download.suggestedFilename());
} finally {
  await browser.close();
}

Replace the URL and locator with the page’s actual controls. Prefer an accessible role, label, or stable test ID over a brittle CSS path. If the click opens a new tab, wait for that page separately; a download event belongs to the browser context that created it.

Browser-context downloads are temporary and are deleted when the context closes. Always call saveAs() or copy the temporary path before closing the context or browser. Check download.failure() when you need to distinguish a canceled or failed transfer from a successful one.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Save rendered HTML with Puppeteer

Puppeteer’s page.content() returns the full current HTML contents of the page, including the document type declaration. Navigate, wait for a condition tied to the application, and then write the string to disk.

Rank #2
Seagate Portable 1TB External Hard Drive HDD – USB 3.0 for PC, Mac, PlayStation, & Xbox, 1-Year Rescue Service (STGX1000400) , Black
  • Easily store and access 1TB to content on the go with the Seagate Portable Drive, a USB external hard drive.Specific uses: Personal
  • Designed to work with Windows or Mac computers, this external hard drive makes backup a snap just drag and drop. Reformatting may be required for Mac
  • To get set up, connect the portable hard drive to a computer for automatic recognition no software required
  • This USB drive provides plug and play simplicity with the included 18 inch USB 3.0 cable
  • The available storage capacity may vary.
import puppeteer from 'puppeteer';
import { writeFile } from 'node:fs/promises';

const browser = await puppeteer.launch();
const page = await browser.newPage();

try {
  await page.goto('https://example.com/app', { waitUntil: 'networkidle2' });
  await page.waitForSelector('main');
  const html = await page.content();
  await writeFile('rendered.html', html, 'utf8');
} finally {
  await browser.close();
}

page.content() captures the DOM state at that moment. It does not bundle external stylesheets, images, fonts, scripts, or API responses into a self-contained archive. Opening the saved file offline may therefore look different or fail to render dynamic behavior. If you need a portable visual artifact, save a PDF instead.

Save a JavaScript-rendered page as PDF

Puppeteer generates PDFs using print CSS media. If the page’s screen layout is the desired result, call emulateMediaType('screen') before generating the file.

import puppeteer from 'puppeteer';

const url = 'https://example.com/report';
const browser = await puppeteer.launch();
const page = await browser.newPage();

try {
  await page.goto(url, { waitUntil: 'networkidle2' });
  await page.waitForSelector('main');
  await page.emulateMediaType('screen');
  await page.pdf({
    path: 'page.pdf',
    printBackground: true,
    format: 'A4'
  });
} finally {
  await browser.close();
}

Use print media when you want the site’s print-specific layout. Set margins, paper size, landscape orientation, page ranges, headers, or footers through the PDF options supported by your library. Playwright also provides page.pdf({ path: 'page.pdf' }).

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Wait for the page you actually need

Readiness is the most common difference between a reliable capture and an empty one. A navigation milestone only proves that a stage of loading completed; it does not prove that an application finished fetching its data.

Prefer a content selector

await page.goto(url, { waitUntil: 'domcontentloaded' });
await page.waitForSelector('[data-testid="results"]');

Choose a selector that appears only when the required content is usable. You can also wait for a known heading, table row, or application state.

Rank #3
Sale
WD 2TB Elements Portable External Hard Drive for Windows, USB 3.2 Gen 1/USB 3.0 for PC & Mac, Plug and Play Ready - WDBU6Y0020BBK-WESN
  • High capacity in a small enclosure – The small, lightweight design offers up to 6TB* capacity, making WD Elements portable hard drives the ideal companion for consumers on the go.
  • Plug-and-play expandability
  • Vast capacities up to 6TB[1] to store your photos, videos, music, important documents and more
  • SuperSpeed USB 3.2 Gen 1 (5Gbps)

Use network idle deliberately

Puppeteer’s documented networkidle2 condition waits for no more than two active network connections for a short period. It is useful for many applications, but analytics, streaming, polling, and chat connections can keep a page busy. Combine it with a selector rather than relying on it alone.

Avoid arbitrary sleeps

A fixed delay may be too short on a slow run and unnecessarily long on a fast one. If a site has a predictable delayed transition, use a short timeout only as a supplement to a selector or navigation condition.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Handle interactions, lazy content, and page state

Consent and modal dialogs

Cookie banners, newsletter prompts, and chat widgets can cover the content or intercept clicks. Locate and dismiss them before capturing. If a dialog appears conditionally, check for it with a short, targeted wait and continue when it is absent.

Lazy-loaded sections

Full-page screenshots and PDFs may omit content that loads only when scrolled into view. Scroll through the page or trigger the application’s “load more” control, then wait for the new elements before saving.

Authentication and redirects

Use an authorized account and establish the session before navigating to the protected URL. Verify the final URL and a logged-in selector; otherwise you may save a login page while believing the capture succeeded. Automation does not, by itself, bypass paywalls, access controls, authorization requirements, bot defenses, or CAPTCHAs.

Downloads that require a preliminary click

Perform any required setup first, then create the download-event promise immediately before the action that starts the transfer. If the action causes navigation instead of a download, wait for the navigation or new page event that the site actually produces.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Reliability, performance, and cleanup

  • Reuse a browser process for a batch, but create an isolated context or page per task when cookies and local storage must not leak.
  • Set navigation and operation timeouts appropriate to the site, and log the final URL, response status, and failure message.
  • Save files to a durable location before closing the context. Clean temporary files after successful persistence.
  • Limit concurrency so the target site and your host are not overwhelmed; more pages do not guarantee faster completion.
  • Use deterministic viewport, timezone, locale, and color-scheme settings when comparing captures.
  • Keep credentials out of source code and logs. Treat downloaded files as sensitive if the page contains private data.

Troubleshooting common failures

“Browser executable not found”

Cause: the browser binary was not downloaded, or the process cannot see it. Fix: run Playwright’s browser-install command, allow Puppeteer’s install script, or install and configure the required browser explicitly.

The saved HTML contains only a loading shell

Cause: the capture ran before the client-side request completed. Fix: wait for a selector representing final content, inspect the page for an error state, and increase the operation timeout only after choosing the right readiness signal.

The PDF is blank or missing images

Cause: rendering occurred before images or fonts were ready, or the page hides content in print media. Fix: wait for the relevant elements, select screen media when appropriate, enable background printing, and verify that resources are reachable in the authenticated context.

The click times out

Cause: an overlay, disabled control, wrong locator, or unhandled consent dialog blocks the action. Fix: inspect the locator, dismiss overlays, wait for the control to be enabled, and avoid forcing a click unless you have confirmed that normal user behavior is safe.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The download disappears

Cause: the temporary browser-context file was deleted during teardown. Fix: call saveAs() before closing the context and check the returned failure status.

Best Value
Sale
UnionSine 1TB Ultra Slim Portable External Hard Drive HDD-USB 3.0
  • 【Upgraded version】 - The mirror logo strip is combined with the striped non-slip design. The rounded corners of the shell are more suitable for holding. The strips play a heat dissipation function to ensure a stable and fast transmission process.
  • 【Ultra-thin and quiet】 - The motherboard adopts JMicron 578 noise-free solution, giving you a quiet working environment. Lightweight and portable size designed to fit in your pocket for easy portability.
  • 【Ultra-Fast Data Transfers】 - Pairing this external hard drive with JMicron 578 solution USB 3.0 and USB 2.0 interfaces enables blazing-fast data transfer. It boasts theoretical read speeds of up to 125MB/s and write speeds of up to 103MB/s.
  • 【Plug and Play】 - With no software to install, just plug it in and the drive is ready to use.The hard disk chip is wrapped with an aluminum anti-interference layer to increase heat dissipation and protect data.
  • 【What You Get】 - 1 x Portable Hard Drive, 1 x USB 3.0 Cable, 1 x User Manual, Gift-type shell packaging ,Three-year manufacturer's warranty and free technical support services.

The page redirects to login or an error page

Cause: missing session state, expired credentials, geographic restrictions, or an application error. Fix: authenticate explicitly, verify the final URL and page markers, and handle the site’s permitted access flow.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

ScreenshotNeo provides a website screenshot API and MCP server when you need a rendered image or PDF without maintaining Playwright or Puppeteer infrastructure. It accepts a URL with one GET request and can return PNG, JPEG, WebP, or PDF.

The basic cURL call is:

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

Python:

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)

Node.js:

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

See the ScreenshotNeo documentation for output and option details. Before capture it can accept consent banners and remove more than 60 known consent platforms, newsletter popups, and chat widgets; each step can be disabled. Bot checks and CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and whether it was billed. Its MCP server offers take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients. The Free plan includes 1,000 screenshots per month without a card; paid plans start at $5 for 3,000 shots.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Create a free ScreenshotNeo account to try the 1,000 included screenshots.

Which method should you use?

  • Choose Playwright when a user action produces the exact attachment you must archive.
  • Choose Puppeteer HTML capture when your downstream process needs the post-script DOM and can fetch its external resources separately.
  • Choose PDF generation when readers need a stable visual document rather than editable markup.
  • Choose an API when you want repeatable captures without installing browsers in your own runtime.

Frequently Asked Questions

Can I download JavaScript-rendered content with only curl?

Not when the content is created after JavaScript executes. curl can retrieve the initial response, but a browser runtime or rendering service is needed for the final DOM or a file created by interaction.

Is saved rendered HTML an offline copy of the site?

No. The HTML contains the current markup, while external CSS, images, fonts, scripts, and API responses remain separate resources.

Why does network idle never occur?

Persistent analytics, polling, streaming, or chat connections can keep the network active. Wait for a page-specific selector and use network idle only as a supporting condition.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Does browser automation defeat a CAPTCHA or paywall?

No. It runs an authorized browser session but does not guarantee bypassing access controls, bot defenses, paywalls, or CAPTCHAs.

Quick Recap

SaleBestseller No. 1
Seagate 2TB Portable Hard Drive | USB 3.0 (STGX2000400)
Seagate 2TB Portable Hard Drive | USB 3.0 (STGX2000400)
This USB drive provides plug and play simplicity with the included 18 inch USB 3.0 cable; The available storage capacity may vary.
$129.99
Bestseller No. 2
Seagate Portable 1TB External Hard Drive HDD – USB 3.0 for PC, Mac, PlayStation, & Xbox, 1-Year Rescue Service (STGX1000400) , Black
Seagate Portable 1TB External Hard Drive HDD – USB 3.0 for PC, Mac, PlayStation, & Xbox, 1-Year Rescue Service (STGX1000400) , Black
This USB drive provides plug and play simplicity with the included 18 inch USB 3.0 cable; The available storage capacity may vary.
$119.80
SaleBestseller No. 3

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.