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

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

For a PNG that matches a modern webpage—including its CSS, fonts, and JavaScript—use a real browser engine such as Playwright or Puppeteer, set the viewport, wait for the page to finish rendering, and save a screenshot. For a user-triggered export of one element inside an existing page, html2canvas can be simpler, but it reconstructs the DOM and has CSS and cross-origin limitations.

Choose the conversion method that fits your HTML

Method Rendering approach Best for Main limitation
Playwright or Puppeteer Captures pixels from a real browser engine Modern websites, JavaScript-heavy pages, repeatable server-side or automated screenshots Requires browser setup and careful control of fonts, viewport, and loading
html2canvas Reconstructs an image from DOM properties in the current browser Letting a visitor export an element without a server-side browser CSS support is not identical to browser rendering; cross-origin images and frames can fail
wkhtmltoimage or a wrapper Uses a dedicated HTML renderer; wrappers may use a browser engine Shell jobs or integration into an existing server workflow Rendering behavior depends on the installed renderer and its age

Use a browser screenshot if fidelity matters. Use html2canvas when client-side convenience matters more than exact browser pixels. For a CLI or PHP application, choose a renderer that fits the deployment environment and compare it with the target pages before relying on it.

Convert a webpage or HTML file with Playwright

Playwright launches Chromium, opens the page, and writes a PNG. This example works with a local HTML file or an HTTP URL. Save it as capture.mjs; install Playwright with npm install playwright and install its browser with npx playwright install chromium.

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.
import { chromium } from 'playwright';

const input = process.argv[2] ?? 'file:///absolute/path/page.html';
const browser = await chromium.launch();

try {
  const page = await browser.newPage({
    viewport: { width: 1280, height: 800 },
    deviceScaleFactor: 1
  });
  await page.goto(input, { waitUntil: 'networkidle' });
  await page.evaluate(() => document.fonts.ready);
  await page.screenshot({
    path: 'page.png',
    type: 'png',
    fullPage: true,
    animations: 'disabled'
  });
} finally {
  await browser.close();
}

Run it with node capture.mjs file:///absolute/path/page.html or pass a full URL such as node capture.mjs https://example.com. Replace the file URI with the actual absolute path on your machine. Local images, stylesheets, and fonts referenced by the HTML must also be accessible to Chromium.

#1 Best Overall
Sale
HTML and CSS: Design and Build Websites
  • HTML CSS Design and Build Web Sites
  • Comes with secure packaging
  • It can be a gift option

Control the output dimensions

The viewport is the browser’s visible CSS-pixel area; it affects responsive breakpoints and layout. fullPage: true captures the scrollable page, including content below the fold. Omit it for a viewport-sized image. Long pages can produce very tall, memory-intensive PNGs, so use a viewport capture or capture defined sections when one huge image is not useful.

For sharper output, increase deviceScaleFactor when creating the page. This renders more image pixels for each CSS pixel, increasing file dimensions and memory use. Playwright’s screenshot API also offers a scale option to control whether output follows CSS-pixel sizing or device-pixel detail. Its CLI supports --full-page and --hires for full-page and higher-resolution captures.

Wait for the right readiness signal

networkidle can be useful, but it is not a guarantee that every page is visually ready: some sites keep network connections open, while others load content after a delay or user interaction. If a specific component matters, wait for it explicitly with a locator, or wait for the application’s own ready state. For pages with lazy-loaded images, scroll through the relevant content before capturing and wait for those images to load. Ensure web fonts are ready with document.fonts.ready; otherwise the screenshot may use fallback fonts.

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

For repeatable captures, keep the viewport, device scale, input data, and page state fixed. Disable animations when supported, and remove or override elements that change with time if they make output inconsistent. Screenshots reflect what the browser rendered at capture time, not an abstracted version of the page.

Use Puppeteer for a Node.js screenshot

Puppeteer follows the same real-browser approach. Install it with npm install puppeteer, save the following as capture-puppeteer.mjs, and run it with Node.js. Change the URL to your local page or target webpage.

import puppeteer from 'puppeteer';

const browser = await puppeteer.launch();
try {
  const page = await browser.newPage();
  await page.setViewport({ width: 1280, height: 800 });
  await page.goto('https://example.com', { waitUntil: 'networkidle2' });
  await page.evaluate(() => document.fonts.ready);
  await page.screenshot({ path: 'page.png', type: 'png', fullPage: true });
} finally {
  await browser.close();
}

Use a file:/// URL for a local HTML document. Puppeteer supports element-level screenshots too: select the element, then call its screenshot method rather than capturing the whole page. As with Playwright, decide whether you need the full scrollable page and make sure the content is loaded before taking the image.

Export an element in the current browser with html2canvas

html2canvas is useful when the conversion should happen in the visitor’s browser and no server-side browser is desired. It returns a Promise resolving to a canvas. This module example captures the element with the ID capture and downloads a PNG:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
<div id="capture">
  <h1>Export this section</h1>
  <p>The page content to capture.</p>
</div>

<script type="module">
  import html2canvas from 'https://cdn.jsdelivr.net/npm/[email protected]/+esm';

  const element = document.querySelector('#capture');
  const canvas = await html2canvas(element);
  const link = document.createElement('a');
  link.download = 'capture.png';
  link.href = canvas.toDataURL('image/png');
  link.click();
</script>

The element must exist when the script runs. If the page’s data, images, or fonts load asynchronously, trigger capture only after they are ready. The project also supports cropping with x, y, width, and height, and a scale option can raise output resolution; using window.devicePixelRatio is one way to align scale with the display. Add data-html2canvas-ignore to an element that should be excluded.

Why html2canvas can look different

html2canvas does not take a literal screenshot. Its documentation says it “does not actually take a screenshot of the page, but builds a representation of it based on the properties it reads from the DOM.” Unsupported or partially supported CSS can therefore look different from the browser’s actual pixels.

Browser security also matters. Cross-origin images may taint the canvas, preventing export, and cross-origin iframe documents cannot be read by the page. Use same-origin assets, configure CORS on resources you control, or use a proxy that returns resources as data URIs when appropriate. If exact rendering of modern CSS or embedded third-party content is essential, capture with a real browser engine instead.

Convert from a command line or PHP application

Command line with wkhtmltoimage

Debian’s reference documents this basic form:

wkhtmltoimage input.html output.png

The utility includes options for local paths, cropping, cookies, and headers. Treat it as a renderer whose behavior must be checked against your pages: compare representative output with a current Chromium screenshot, particularly when modern CSS or JavaScript affects the result.

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.

PHP with Browsershot

Spatie Browsershot is a PHP wrapper that delegates rendering to Puppeteer and headless Chrome. Its documented URL pattern is:

Browsershot::url('https://example.com')->save($pathToImage);

Use a PNG filename, such as page.png, for image output. Browsershot also documents HTML input through Browsershot::html(...) and htmlFromFilePath(...). The server needs the required Node.js, Puppeteer, and Chrome installation; a PHP package alone does not provide the browser runtime.

Prepare the page for reliable PNG output

  • Set the viewport: Choose dimensions that trigger the intended responsive layout; do not rely on a machine’s default window size.
  • Set resolution deliberately: Higher device scale or screenshot scale creates more pixels and a larger image.
  • Wait for visual content: Confirm that application data, web fonts, and relevant images have loaded; network idleness alone may not be sufficient.
  • Check external resources: Verify that fonts and images are accessible, and account for CORS, credentials, and caching where relevant.
  • Choose full-page or viewport output: Full-page PNGs can be extremely tall and consume substantial memory; use them only when the below-the-fold content belongs in one image.
  • Remove sources of variation: Disable animations or hide blinking, time-dependent UI when deterministic output matters.
  • Choose a background intentionally: Check whether the page background is opaque or whether transparent output is required; verify the resulting image rather than assuming a renderer’s default.
  • Test representative pages: Include pages with the relevant CSS, scripts, fonts, lazy content, and embedded resources before standardizing a tool.

Troubleshoot common HTML-to-PNG failures

The PNG is blank or content is missing

The page may have been captured before JavaScript populated it, an element may be outside the captured region, or a lazy image may not have loaded. Wait for the specific element or application-ready state, scroll relevant content into view, and confirm whether you intended a viewport or full-page capture.

The layout or typography differs between runs

Check for an unset viewport, fonts that finish loading after the capture, animations, changing timestamps, or external content that varies. Fix the viewport and device scale, wait for fonts and application content, and disable or override time-dependent effects where possible.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #4
Sale
Web Design with HTML, CSS, JavaScript and jQuery Set
  • Brand: Wiley
  • Set of 2 Volumes
  • A handy two-book set that uniquely combines related technologies Highly visual format and accessible language makes these books highly effective learning tools Perfect for beginning web designers and front-end developers

html2canvas export fails for an image or iframe

Inspect whether the asset is cross-origin. A cross-origin image can taint the canvas; an inaccessible cross-origin iframe cannot be rendered from the page’s DOM. Serve assets from the same origin, configure CORS where you control the host, or use an appropriate proxy. For an iframe you cannot access, use a browser screenshot if you are authorized to capture the rendered page.

Playwright or Puppeteer cannot launch in deployment

The browser executable or its operating-system dependencies may be missing from the runtime. Install the browser version required by the package and its system dependencies in the deployment environment; verify a minimal launch-and-screenshot job there rather than assuming a successful local run transfers to CI or a server.

The image is too large or slow to generate

A full-page capture of a long document, especially at high device scale, creates many pixels and uses more memory. Capture only the viewport or a specific element, reduce the scale, or split the page into sections. Check whether a whole-page image is actually needed by the destination.

Local files cannot load their assets

Use an absolute file:/// URL and confirm paths referenced by the HTML resolve in the browser process. If local-resource restrictions or relative paths cause trouble, serve the files from a local HTTP server and navigate to that address instead.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

If you need a webpage screenshot without installing and managing a browser runtime, ScreenshotNeo provides a website screenshot API and MCP server. The API accepts one GET request and can return PNG, JPEG, WebP, or PDF. For PNG output, request it using the service’s documented parameters; the basic one-call example saves the response as 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

See the ScreenshotNeo API documentation for request options and output configuration. Cookie and consent banners are accepted like a visitor and removed, along with supported newsletter popups and chat widgets, before capture; each step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, with response headers indicating the page verdict and billing status. Its MCP server offers take_screenshot, get_page_info, and capture_pdf for AI agents. The Free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 shots.

Sign up for ScreenshotNeo’s free plan to try 1,000 screenshots a month without a card.

Which method should you use?

Choose Playwright or Puppeteer when the PNG must reflect a modern browser-rendered page, including JavaScript and current CSS. Choose html2canvas for a convenient in-page export of a controlled element when its fidelity and cross-origin limits are acceptable. Choose a CLI tool or PHP wrapper to fit an existing server workflow, but validate its rendering against the pages you need to convert. In every case, control the viewport and wait for the content that matters before capturing.

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

Frequently Asked Questions

Can I convert an HTML file to PNG without an internet connection?

Yes, a browser tool such as Playwright can open a local file with a file:/// URL. Any fonts, images, scripts, or stylesheets the document references must also be available locally or through a network connection.

Does html2canvas save the whole webpage automatically?

No. It renders the element passed to it; select the page container or another target element explicitly. Use a browser screenshot with full-page capture when you need the document’s full scrollable page.

Can a PNG have a transparent background?

It depends on the capture method and page styling. Check the renderer’s transparency and background options, and verify the exported PNG; a page’s CSS background may make the result opaque.

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.