Free tools Windows power users keep installed

One-click scans. No signup required.

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

Use a real browser screenshot when you need a PNG of rendered HTML. Playwright and Puppeteer load the page, apply CSS, fonts, images, and JavaScript, then save the browser output as PNG. Choose a viewport shot for the visible screen, a full-page shot for the document’s scrollable extent, or an element shot for one component. For an in-page alternative, html2canvas reconstructs a selected DOM region in a canvas, but it is not a pixel-perfect browser screenshot and can omit unsupported or cross-origin content.

Choose the right export method

Need Recommended route Important trade-off
Repeatable automation or server-side PNGs Playwright or Puppeteer Uses a real browser renderer; you must install and manage browser automation and wait for page readiness.
Capture a DOM region inside an existing page html2canvas Runs in the page, but reconstructs pixels from DOM data rather than taking a true screenshot.
Capture the entire document Full-page browser screenshot Includes the page’s current scrollable extent, not content that an infinite-scroll page has not loaded.

Playwright’s screenshot API is documented at playwright.dev/docs/api/class-page; Puppeteer’s guide is at pptr.dev/guides/screenshots. The methods below save PNG files explicitly.

Export HTML as PNG with Playwright

Install the package and browser

npm install -D playwright
npx playwright install chromium

Capture the visible viewport

import { chromium } from 'playwright';

const browser = await chromium.launch();
const page = await browser.newPage({ viewport: { width: 1440, height: 900 } });
await page.goto('https://example.com', { waitUntil: 'networkidle' });
await page.screenshot({ path: 'viewport.png', type: 'png' });
await browser.close();

page.goto() loads the URL and waitUntil: 'networkidle' waits for network activity to settle. For pages with continuing analytics or streaming requests, use a targeted readiness condition instead of waiting indefinitely.

Capture the full scrollable page

await page.screenshot({ path: 'full-page.png', fullPage: true, type: 'png' });

Full-page mode captures the page extent that exists at capture time. It does not automatically trigger an infinite-scroll loader. Scroll or click a “Load more” control first, then capture.

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

Capture one HTML element

await page.locator('.invoice').screenshot({ path: 'invoice.png', type: 'png' });

Use a stable selector such as an ID, data attribute, or component class. If the element is hidden, detached, or covered by an animation, the capture can fail or contain an intermediate state.

Control output dimensions and density

await page.screenshot({
  path: 'retina.png',
  type: 'png',
  scale: 'device'
});

Playwright supports scale: 'css' (one output pixel per CSS pixel) and scale: 'device' (device pixels). Device scale can produce a larger, higher-resolution file. Set the viewport deliberately when exact dimensions matter.

Make dynamic pages deterministic

await page.goto('https://example.com/report');
await page.waitForSelector('#report-ready');
await page.evaluate(() => document.fonts.ready);
await page.screenshot({ path: 'report.png', type: 'png' });

Wait for the selector that proves the relevant content is ready. Also wait for fonts, images, charts, or other assets that affect the image. Hide animations with CSS or pause them before capture when a stable frame is required.

Export HTML as PNG with Puppeteer

Install and capture a viewport

npm install puppeteer
import puppeteer from 'puppeteer';

const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.setViewport({ width: 1440, height: 900 });
await page.goto('https://example.com', { waitUntil: 'networkidle0' });
await page.screenshot({ path: 'viewport.png', type: 'png' });
await browser.close();

Use full-page or element screenshots

await page.screenshot({ path: 'full-page.png', fullPage: true, type: 'png' });
await page.locator('.invoice').screenshot({ path: 'invoice.png', type: 'png' });

Puppeteer’s screenshot guide covers viewport, full-page, and element captures. Prepare the page and its assets before calling screenshot(); otherwise late fonts, images, or JavaScript can produce incomplete output.

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

Use html2canvas for an in-page element

Basic browser example

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/html2canvas.min.js"></script>

html2canvas reads DOM information and paints a canvas; it does not take an actual browser screenshot. Its documentation states that the result may not be 100% accurate because only supported CSS properties are rendered: html2canvas documentation.

Cross-origin images and frames

Images generally need to be same-origin or served with suitable CORS headers and configuration. Cross-origin iframes cannot be read because of browser security rules. If fidelity to the browser is more important than running inside the page, use Playwright or Puppeteer instead. The html2canvas FAQ also warns that oversized canvases can become blank or partial when browser or platform dimension and area limits are exceeded: html2canvas FAQ.

PNG settings, readiness, and page scope

PNG does not use a quality setting

PNG is lossless. Unlike JPEG, it does not use a lossy quality value in these screenshot APIs. Choose PNG when you need crisp text, transparency, or pixel-preserving output; resize afterward if the resulting dimensions are too large.

Viewport versus full page

  • Viewport: captures what a user can see at the configured width and height.
  • Full page: captures the current scrollable document extent.
  • Element: captures the bounding box of a selected component.

A page with lazy images, deferred charts, consent dialogs, or animations needs explicit preparation. A full-page flag does not guarantee that content requiring user scrolling has loaded.

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

Troubleshooting common failures

The PNG is blank or only partly rendered

Wait for a meaningful selector, fonts, and required images instead of capturing immediately after navigation. For html2canvas, reduce the target size and check browser canvas limits; an oversized canvas can export blank or partial output.

Fonts or images are missing

Confirm the asset requests succeed, wait for document.fonts.ready, and ensure the screenshot runs after lazy assets are loaded. In html2canvas, fix same-origin or CORS headers for images.

The screenshot differs from what you see manually

Set the same viewport, device scale, color scheme, timezone, and authentication state. Disable animations and wait for the exact application state you intend to document. DOM reconstruction can differ from browser pixels when CSS is unsupported.

Full-page output omits lower content

Load infinite-scroll content explicitly by scrolling, clicking pagination, or calling the application’s documented load mechanism. Then capture the resulting extent.

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

A selector capture fails

Check that the selector matches one visible element at capture time. Wait for it to attach and become visible, and avoid selectors tied to generated class names.

Navigation never becomes idle

Some pages maintain long-lived connections. Replace a global network-idle wait with a specific selector, a bounded delay, or an application-ready flag, and keep an overall timeout so jobs cannot hang.

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

Performance, reliability, and cost considerations

Launching a browser for every image adds startup time and memory use. For batches, reuse one browser process and create separate pages or contexts. Keep viewport sizes and wait conditions consistent so outputs are comparable. Cache unchanged URLs when your workflow permits it, but invalidate the cache when content, authentication, or CSS changes.

There is no universal fastest or most accurate choice: results depend on page complexity, assets, browser version, viewport, and readiness logic. Playwright and Puppeteer provide browser fidelity; html2canvas avoids a separate browser but accepts rendering and security limitations.

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

Or skip the browser setup

ScreenshotNeo is a screenshot API and MCP server. Send one GET request and receive PNG, JPEG, WebP, or PDF output. It accepts cookie and consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be disabled. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the result with X-Page-Verdict and X-Billed headers.

One-call cURL example

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 complete option list and authentication details in the ScreenshotNeo documentation.

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

ScreenshotNeo also supports full-page and element capture, dark mode, device presets and custom viewports, retina scale, PDF controls, custom CSS and JavaScript, clicks, selector or network-idle waits, request blocking, headers, cookies, user agents, authorization, timezone and geolocation, transparent backgrounds, resizing, chosen cache TTLs, signed image links, asynchronous jobs with signed webhooks, bulk capture for up to 100 URLs per call, usage reporting, and an OpenAPI specification. Its parameter names are compatible with those used by other screenshot APIs, which can simplify migration. Claude, Cursor, and other MCP clients can use its take_screenshot, get_page_info, and capture_pdf tools.

The Free plan includes 1,000 shots per month with no card. Paid plans start at $5 for 3,000 shots; yearly billing gives two months free. Create a free ScreenshotNeo account to start with the 1,000 monthly screenshots.

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

Decision checklist

  • Use Playwright or Puppeteer for browser-faithful automated captures.
  • Use html2canvas only when in-page operation and a selected DOM region matter more than pixel fidelity.
  • Choose viewport, full-page, or element scope before writing capture code.
  • Wait for the actual content, fonts, images, and application state required in the PNG.
  • Set viewport and scale deliberately when dimensions or density matter.
  • Inspect output for clipping, missing assets, overlays, and dynamic-state errors.

Frequently Asked Questions

Can I export HTML to PNG without a browser?

A browser engine is the dependable route for rendered HTML. html2canvas runs in the page but reconstructs the image and has CSS and cross-origin limitations; an API such as ScreenshotNeo handles browser capture remotely.

Does full-page screenshot include infinite-scroll content?

Only content loaded into the document before capture is included. Trigger additional loading yourself, then take the full-page screenshot.

Why is my PNG larger than expected?

A large viewport, full-page height, device-pixel scale, or oversized canvas increases dimensions. Use CSS scale, a smaller viewport, or resize the finished image.

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.