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

Use a real browser when the page builds its content with JavaScript. For a mostly static page, your browser’s “Save page” (complete) option or wget -p -k -E URL can save HTML and its CSS, images, and other requisites. Those methods do not execute JavaScript, however. For a dependable copy of a JavaScript-rendered page, run it in Playwright, wait for the rendered state, and then save the HTML, PDF, screenshot, or a file download. The right method depends on whether you need editable source, an offline site, a visual record, or the file the site offers for download.

What “download a web page” can mean

A modern page is a collection of different things. The initial HTML provides structure; CSS controls presentation; JavaScript is parsed, interpreted, compiled, and executed after CSS is handled; images and fonts arrive as additional requests; and data may be fetched only after the page loads or after a user action. Saving the first HTML response therefore may produce an empty shell or an unstyled page.

  • Editable offline copy: HTML plus local CSS, images, fonts, and other assets, with links rewritten to local paths.
  • Rendered record: a PDF or image of exactly what a browser displayed at capture time.
  • Original download: a PDF, ZIP, CSV, or other file generated or served by the page.
  • Repeatable archive: a scripted process that can authenticate, click controls, wait for data, and run again.

Choose the output before choosing a tool. A screenshot or PDF preserves appearance but is not an editable website. An asset archive can be edited but may not reproduce runtime behavior, WebSocket data, or third-party services.

Quick decision guide

Need Best first method JavaScript runs? Typical result
One static article for offline reading Browser Save Page (complete) No HTML file and an asset folder
Repeatable command-line mirror of a static page wget -p -k -E No Local HTML with fetched requisites and rewritten links
Content inserted or changed by JavaScript Playwright Yes Rendered HTML, PDF, screenshot, or captured resources
A button that downloads a file Playwright download event Yes The site-provided file saved with its suggested name
Visual evidence only Browser print to PDF, screenshot, or ScreenshotNeo Yes (in a browser capture) Non-editable visual artifact

Method 1: Save a static page from your browser

Chrome, Edge, Firefox, and similar browsers

  1. Open the page and let visible images and text finish loading.
  2. Choose File > Save Page As, or press Ctrl+S on Windows/Linux or Command+S on macOS.
  3. Select Web Page, Complete (wording varies slightly by browser) and save.
  4. Keep the generated HTML file and its companion asset folder together. Open the HTML file locally to verify it.

The complete option normally downloads linked stylesheets, images, and other page requisites. A single-file or “HTML only” option is easier to move but may omit resources or inline them in a form that is harder to edit. Relative links can break when files are moved out of their folder.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
#1 Best Overall
Elebase USB to USB C Adapter for iPhone 18 Pro Max,USBC Car Charger Adapter
  • Read Before You Buy — No Video Output: These adapters support charging and USB 2.0 data transfer, but cannot transmit video signals. Except for standard USB webcams (which use USB data only), they are not compatible with HDMI/DisplayPort cables, video-capable USB-C hubs, or docking stations with video output.
  • Convert USB-A Ports to USB-C: Designed to connect USB-C earphones, cables, flash drives, card readers, and other USB-C accessories to standard USB-A ports. Plug-and-play with no drivers or software required.
  • Aluminum Alloy Housing: Built with a sturdy aluminum alloy shell that aids in heat dissipation and protects against daily wear and scratches. Designed to maintain a stable and secure connection.
  • Compact & Travel-Friendly: The ultra-compact design allows the adapter to stay plugged into your device without blocking adjacent ports or adding bulk, reducing wear and tear on your original USB ports.
  • 12-Month Warranty: Backed by a 12-month manufacturer warranty for peace of mind. Designed to meet strict quality control standards for reliable everyday performance.

What this method cannot preserve

JavaScript does not keep running just because its source file was saved. A page that fills a table after an API call, requires scrolling to load cards, or displays content after a click may save only its initial shell. Cross-origin resources, authenticated requests, service-worker state, and data generated on a server may also be unavailable offline. Compare the local copy with the live page before treating it as complete.

Method 2: Download requisites with wget

Basic command

Install GNU Wget through your operating system’s package manager, then run:

wget -p -k -E https://example.com/page.html
  • -p (or --page-requisites) fetches resources needed to display the page, such as CSS and images.
  • -k (or --convert-links) rewrites links so the saved copy can refer to local files.
  • -E (or --adjust-extension) gives saved HTML an appropriate .html extension.

Use an output directory when collecting several pages:

wget -p -k -E -P ./offline-copy https://example.com/page.html

Open the resulting HTML locally and inspect the browser’s developer console and network panel for missing files. Wget is a resource fetcher, not a browser runtime: it does not execute page JavaScript. It can therefore save the scripts themselves while still missing the content those scripts create.

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

Wget edge cases

  • Resources loaded only after a click, scroll, timer, or API response are not known to Wget from the initial document.
  • Relative-link rewriting helps local navigation but does not turn server-side routes, login sessions, or live APIs into offline data.
  • Some sites block automated requests or require headers and cookies. Do not bypass access controls; use an authorized session and follow the site’s terms.
  • For a whole site, scope your crawl carefully. An unrestricted recursive command can fetch far more than intended.

Method 3: Download a JavaScript-rendered page with Playwright

Playwright launches a real browser engine, so scripts execute and network requests occur as they would for a visitor. This is the practical choice when the saved result must include content that appears only after rendering.

Rank #2
Anker USB-C Hub, 5-in-1 USB Hub for Laptops, 4K HDMI Multiport Adapter
  • 5-in-1 USB-C Hub: Experience comprehensive connectivity featuring a Power Delivery input, two USB-A 2.0 ports, a USB-A 3.0 port, and an HDMI port. (Note: The USB-C power delivery input port is only for connecting an external wall charger to power your laptop and cannot power peripheral devices.)
  • 90W Pass-Through Charging: Achieve optimal charging with 90W pass-through power to your laptop, supported by a total input of 100W, with the hub reserving 10W for operational efficiency. (Note: Wall charger not included.)
  • Quick Data Transfers: Accelerate your productivity with rapid data transfers using a high-speed 5Gbps USB 3.0 port and two 480Mbps USB 2.0 ports.
  • 4K HDMI Display: Enhance your visual experience with a hub capable of delivering 4K resolution at 30Hz in both mirror and extend modes. Please note that this hub is compatible with MacBook (macOS 12 and newer), Windows 10 and 11, ChromeOS, and laptops equipped with DP Alt Mode and Power Delivery. Note: This device is not compatible with Linux.
  • What You Get: Anker USB-C Hub (5-in-1, 4K HDMI), welcome guide, 18-month warranty, and our friendly customer service.

Install and create a project

mkdir page-capture
cd page-capture
npm init -y
npm install -D playwright
npx playwright install chromium

Save rendered HTML, a PDF, and a screenshot

Create capture.mjs:

import { chromium } from 'playwright';

const url = process.argv[2] ?? 'https://example.com';
const browser = await chromium.launch();
const page = await browser.newPage({
  viewport: { width: 1440, height: 1000 },
  deviceScaleFactor: 1
});

try {
  await page.goto(url, { waitUntil: 'domcontentloaded', timeout: 90_000 });
  await page.waitForLoadState('networkidle', { timeout: 30_000 }).catch(() => {});
  await page.locator('body').waitFor({ state: 'visible', timeout: 30_000 });

  await page.screenshot({ path: 'page.png', fullPage: true });
  await page.pdf({ path: 'page.pdf', format: 'A4', printBackground: true });
  const renderedHtml = await page.content();
  await Bun.write('page-rendered.html', renderedHtml).catch(async () => {
    const fs = await import('node:fs/promises');
    await fs.writeFile('page-rendered.html', renderedHtml, 'utf8');
  });
} finally {
  await browser.close();
}

Run it with node capture.mjs https://example.com/article. The saved HTML contains the DOM after scripts have modified it, but it is not automatically a self-contained archive: stylesheet URLs, images, fonts, and API-backed interactions may still point to the network. A PDF or full-page screenshot is often the more faithful offline record.

Wait for the right condition

networkidle is useful but not universal. Analytics, advertisements, and long-lived connections can prevent a quiet network. Prefer a meaningful selector when you know what proves the page is ready:

await page.goto('https://example.com/dashboard', { waitUntil: 'domcontentloaded' });
await page.locator('[data-testid="results"]').waitFor({ state: 'visible', timeout: 30_000 });

For a known animation or delayed request, use a bounded delay only as a last resort:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
await page.waitForTimeout(2000);

Waiting for a selector is more reliable than guessing a number of milliseconds. If lazy-loaded images depend on scrolling, scroll before capture and wait for the images’ complete state or a page-specific marker.

Save a file initiated by a button

For a genuine browser download, listen before clicking. Playwright’s API dispatches a download event from the page; save the resulting object:

Rank #3
Sale
Anker USB C Hub, 7in1 Multi-Port USB Adapter, 4K@60Hz USBC to HDMI Splitter
  • Sleek 7-in-1 USB-C Hub: Features an HDMI port, two USB-A 3.0 ports, and a USB-C data port, each providing 5Gbps transfer speeds. It also includes a USB-C PD input port for charging up to 100W and dual SD and TF card slots, all in a compact design.
  • Flawless 4K@60Hz Video with HDMI: Delivers exceptional clarity and smoothness with its 4K@60Hz HDMI port, making it ideal for high-definition presentations and entertainment. (Note: Only the HDMI port supports video projection; the USB-C port is for data transfer only.)
  • Double Up on Efficiency: The two USB-A 3.0 ports and a USB-C port support a fast 5Gbps data rate, significantly boosting your transfer speeds and improving productivity.
  • Fast and Reliable 85W Charging: Offers high-capacity, speedy charging for laptops up to 85W, so you spend less time tethered to an outlet and more time being productive.
  • What You Get: Anker USB-C Hub (7-in-1), welcome guide, 18-month warranty, and our friendly customer service.
import { chromium } from 'playwright';

const browser = await chromium.launch();
const page = await browser.newPage();
try {
  await page.goto('https://example.com/export', { waitUntil: 'domcontentloaded' });
  const downloadPromise = page.waitForEvent('download');
  await page.getByText('Download file').click();
  const download = await downloadPromise;
  await download.saveAs('./downloads/' + download.suggestedFilename());
} finally {
  await browser.close();
}

Create the downloads directory first, or choose an absolute path. If the click opens a new tab instead of a download, wait for a popup and handle that page; if it generates data with JavaScript, capture the response or use the application’s documented export endpoint rather than pretending it is a static asset.

Authenticated and interactive pages

Automate the permitted login flow, or load a previously saved browser context. Supply only the headers, cookies, user agent, timezone, or geolocation that your authorized workflow requires. Click consent controls, expand accordions, select filters, and scroll before saving. Never put passwords or tokens directly in source control; read them from environment variables or a secret manager.

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

Making a JavaScript page genuinely usable offline

Rendered HTML alone is not a complete website. For an offline package, you must collect the resources that the final DOM references and rewrite those references to local files. A browser-based recorder can observe requests while the page runs; a custom script can download permitted responses and map each URL to a local path. This is engineering work rather than a single Playwright option, especially when resources are cross-origin, protected, or generated dynamically.

  • Check CSS url(...) references for fonts and background images, not just <img> elements.
  • Record the final URL after redirects and preserve query strings when they identify a resource.
  • Inline or archive data fetched by XHR/fetch if the offline copy must show it later.
  • Expect service workers, WebSockets, payment widgets, maps, and other live integrations to remain unavailable offline.
  • Verify links, images, fonts, and interactive controls from a disconnected network before distributing the archive.

Or skip the browser setup

When you need a rendered screenshot or PDF rather than an editable source archive, ScreenshotNeo provides a one-request capture API. It accepts the URL and returns PNG, JPEG, WebP, or PDF. Before capture it accepts cookie/consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be disabled. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers report the page verdict and billing status.

Use the ScreenshotNeo API documentation for all options. This cURL request saves a WebP image:

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}`);

It also supports full-page capture with lazy images loaded, CSS-selector element capture, dark mode, 12 device presets or any viewport, retina scale, PDF paper size/margins/landscape/page ranges, custom CSS and JavaScript, pre-capture clicks, hidden selectors, waits for selectors/delays/network idle, blocked ads/trackers/requests/resource types, custom headers/cookies/user agents/Authorization, timezone and geolocation, transparent backgrounds, resizing, chosen cache TTLs, signed image links, asynchronous jobs with signed webhooks, bulk capture of up to 100 URLs per call, a usage API, and an OpenAPI specification. Parameter names used by other screenshot APIs also work, easing migration. An MCP server exposes take_screenshot, get_page_info, and capture_pdf to Claude, Cursor, and other MCP clients.

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.
Rank #4
Sale
UGREEN USB to USB C Adapter Combo 4-Pack, 10Gbps USB C Converter Space Gray
  • Dual Converters, Infinite Potential:Includes 2× USB C male to USB A female adapters and 2× USB A male to USB C female adapters. Perfect for a wide range of uses—tablets with Bluetooth keyboards, expand USB ports on macbook, and more. Two different converters for all your daily needs
  • Next-Level 10Gbps & 3A Charging: No more slow 480Mbps, this usb to usb c adapter has a transfer speed of up to 10Gbps, allowing you to do more transferring in less time. This usb adapter fits both USB A and USB C charger, supporting up to 3A fast charging
  • Upgraded Exquisite Craftsmanship: With an aluminum alloy housing and metal connector, the usbc to usb adapter is extremely durable and sturdy. Rigorously tested to withstand more than 10,000 times of plugging and unplugging, ensuring long-lasting performance
  • Broad Compatible: The usb c to usb adapter widely supports all USB C/ USB A devices like laptops, tablets, cellphones, car chargers, and phone chargers. Such as compatible with MacBook Pro/Air 2023/2022, Thunderbolt 4/3 Devices,Apple MagSafe Watch 9/8/7/SE/Ultra, iPad Pro 2022/2021, Samsung Galaxy S23/S20/S10, and iPhone 17/16/15 Pro. Plug and play
  • Please Note: To reach 10Gbps speed, keep the cable under 3.3 ft. For USB A Male to USB C adapters, try flipping the USB C connector. USB C Male to USB A adapters support bidirectional 10Gbps transfer within 3.3 ft

The Free plan includes 1,000 shots per month with no card. Paid plans are Starter $5 for 3,000, Growth $15 for 15,000, Pro $39 for 60,000, Scale $99 for 250,000, and Business $249 for 1,000,000; yearly billing gives two months free, and every feature is on every plan. Start with 1,000 free screenshots a month—no card required.

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

Troubleshooting

The saved page is unstyled

Confirm you used the complete-page option or -p, kept the asset folder beside the HTML, and opened the correct file. A local browser console will identify missing CSS URLs or blocked mixed-content requests.

Text or cards are missing

The content is probably injected after load. Use Playwright, wait for a page-specific selector, perform the required click or scroll, and capture again. Do not assume a longer Wget run will execute JavaScript.

Playwright times out

Check DNS and connectivity, increase the navigation timeout for a demonstrably slow authorized site, and replace an unconditional networkidle wait with a meaningful selector. Capture a trace or console errors to find the request that never completes.

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

The download event never fires

Make sure the listener is created before the click and that the control really downloads a file. Handle popups separately, and check whether a consent dialog, login screen, or bot check intercepted the click.

Best Value
Anker USB C Hub, 5-in-1 USBC to HDMI Splitter with 4K Display
  • 5-in-1 Connectivity: Equipped with a 4K HDMI port, a 5 Gbps USB-C data port, two 5 Gbps USB-A ports, and a USB C 100W PD-IN port. Note: The USB C 100W PD-IN port supports only charging and does not support data transfer devices such as headphones or speakers.
  • Powerful Pass-Through Charging: Supports up to 85W pass-through charging so you can power up your laptop while you use the hub. Note: Pass-through charging requires a charger (not included). Note: To achieve full power for iPad, we recommend using a 45W wall charger.
  • Transfer Files in Seconds: Move files to and from your laptop at speeds of up to 5 Gbps via the USB-C and USB-A data ports. Note: The USB C 5Gbps Data port does not support video output.
  • HD Display: Connect to the HDMI port to stream or mirror content to an external monitor in resolutions of up to 4K@30Hz. Note: The USB-C ports do not support video output.
  • What You Get: Anker 332 USB-C Hub (5-in-1), welcome guide, our worry-free 18-month warranty, and friendly customer service.

Images are blank in a PDF or screenshot

Wait for lazy images, scroll through the page, and verify that image requests succeed. Cross-origin canvas restrictions and resources requiring authentication may prevent a visual capture even when text is visible.

The offline copy works once, then fails

It likely depends on live APIs, service workers, expiring URLs, or a missing font/resource. Archive the required responses, rewrite URLs, and test with network access disabled.

Reliability, cost, and legal checks

  • Pin your Playwright and browser versions; browser menus and automation behavior change over time.
  • Use bounded timeouts, retries for transient network failures, and deterministic readiness selectors.
  • Record the source URL, capture time, viewport, locale, and authentication state with each archive.
  • Large pages consume disk, bandwidth, and memory. Limit scope, block irrelevant resources where appropriate, and clean temporary browser profiles.
  • Check copyright, licensing, robots policies, terms of service, privacy obligations, and authorization before archiving or redistributing another person’s page. Technical ability is not permission.

Frequently Asked Questions

Does saving HTML preserve a page’s JavaScript behavior?

Usually no. It preserves markup and possibly script files, but offline behavior still needs the runtime, APIs, cookies, and other services those scripts expect.

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

Should I choose a PDF or an HTML archive?

Choose PDF for a stable visual record; choose an HTML-and-assets archive when you need to inspect or edit source. Neither automatically preserves every interactive feature.

Can I archive a page behind a login?

Yes, with an authorized session: automate login or load a saved context, keep secrets out of code, and verify that private data is handled according to your obligations.

Why does a local copy differ from the live page?

The live page may fetch changing data, use time-sensitive assets, detect a different viewport or locale, or depend on services that are unavailable offline. Record those conditions and compare the copy immediately after capture.

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.

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