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

To turn a rendered React component into a downloadable image in the browser, attach a ref to its DOM element, pass that element to html2canvas, then export the returned canvas. This is a client-side conversion—not a literal browser screenshot—so CSS fidelity, cross-origin images and canvas size can affect the result.

Convert a React element to a PNG

React components need to be rendered in a browser before a DOM-to-canvas library can inspect them. The example below captures a card, requests a transparent background, uses the device pixel ratio for sharper output, and downloads a PNG. It also handles a missing element, waits for fonts where the browser exposes the Font Loading API, and reports capture or export errors rather than failing silently.

Install the package

The html2canvas guide currently shows this installation command:

npm install @html2canvas/html2canvas

Confirm the package name and import form against the current guide and your project setup when installing; package distribution details can change.

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

Component example

import { useRef, useState } from 'react';
import html2canvas from '@html2canvas/html2canvas';

export default function ExportCard() {
  const cardRef = useRef(null);
  const [status, setStatus] = useState('');

  async function downloadImage() {
    const element = cardRef.current;
    if (!element) {
      setStatus('The card is not available to capture yet.');
      return;
    }

    setStatus('Preparing image…');
    try {
      if (document.fonts?.ready) {
        await document.fonts.ready;
      }

      const canvas = await html2canvas(element, {
        backgroundColor: null,
        scale: window.devicePixelRatio || 1,
        useCORS: true,
      });

      const blob = await new Promise((resolve, reject) => {
        canvas.toBlob((result) => {
          if (result) resolve(result);
          else reject(new Error('The browser could not create an image file.'));
        }, 'image/png');
      });

      const downloadUrl = URL.createObjectURL(blob);
      const link = document.createElement('a');
      link.href = downloadUrl;
      link.download = 'card.png';
      link.click();
      URL.revokeObjectURL(downloadUrl);
      setStatus('Image downloaded.');
    } catch (error) {
      console.error('Could not capture the card:', error);
      setStatus('Image capture failed. Check the images and styles, then try again.');
    }
  }

  return (
    <section>
      <div ref={cardRef} className="export-card">
        <h2>Your report</h2>
        <p>This rendered React element will be exported.</p>
      </div>
      <button type="button" onClick={downloadImage}>
        Download PNG
      </button>
      <p role="status" aria-live="polite">{status}</p>
    </section>
  );
}

If you paste this into a JSX file, use normal JSX tags such as <section> in the source; the escaped tags above keep the example valid inside an HTML article. Add your own styles to .export-card and its children.

What the options do

  • backgroundColor: null requests a transparent canvas background. Use a color value instead if the exported image should have a solid backdrop.
  • scale sets the output scale. The device-pixel-ratio setting follows the project’s high-DPI example; higher values create more pixels and can increase memory use.
  • useCORS: true attempts to load eligible cross-origin images with CORS. It does not bypass the remote server’s CORS policy.
  • toBlob() is a browser canvas API used here to create the downloadable file without first building a large base64 data URL. The html2canvas result is still a canvas.

The project also demonstrates exporting with canvas.toDataURL('image/png') and downloading through an anchor. That is convenient for small images, while toBlob() can be preferable for larger outputs.

What html2canvas captures—and what it does not

html2canvas reads the DOM and styles and reconstructs an image on a canvas. Its documentation cautions that the result may not be fully accurate because it “does not make an actual screenshot” but builds one from information available on the page. Unsupported or incompletely implemented CSS may therefore look different from the live browser rendering.

This distinction matters when the output must exactly match a browser viewport, when the component relies on complex styling, or when a screenshot is needed on a server. Test the real component in the browser and compare its exported image rather than assuming every CSS property will transfer unchanged.

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

Wait for assets before capture

Capturing before fonts or images finish loading can produce a result that differs from the visible page. The example waits for the browser’s font readiness promise when available. Check your app’s own image-loading behavior as well; an image that has not loaded by capture time cannot be expected to appear in the output. There is no single font-readiness recipe that fits every app and resource setup.

Know when to use a different method

Approach Best fit Main trade-off
html2canvas in the page Client-side export of a rendered React element Reconstructs DOM and styles; CSS coverage, canvas security and canvas dimensions constrain the result.
Headless browser screenshot, such as Puppeteer or Playwright Server-side screenshot generation requiring browser rendering Requires browser automation infrastructure; deployment cost and API trade-offs depend on your setup.
Native browser-extension screenshot API Capturing a browser tab or viewport from an extension A different use case from a normal React site; extension APIs are the more appropriate route for a true tab screenshot.

The html2canvas FAQ points to Puppeteer or Playwright for server-side screenshots and native extension APIs for extension capture. It does not establish a universal winner or a comparative performance benchmark. Choose based on where the code runs and the fidelity required.

Images, CORS and export security

A canvas can become tainted when it includes an image from another origin that does not permit the browser to read it. Once that happens, reading or exporting the canvas may fail. Start by checking whether each image is same-origin. For remote assets, the image server must send CORS headers that allow your page’s origin; setting useCORS: true is only an attempt to use that permission.

A proxy can help only if it is configured to retrieve and serve the image under a policy that allows the browser to use it. Do not treat allowTaint as an export fix: allowing a tainted canvas does not make its contents readable for a downloadable image.

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

Troubleshoot common output problems

Styles or layout differ from the page

Some CSS properties may not be implemented by the renderer. Check the project’s supported-features documentation for the particular property, then reduce the problem to a small component if needed. If the output includes a different viewport layout, inspect the element’s size and the page dimensions used during capture.

Images are missing or export throws an error

  • Confirm the image finished loading before capture.
  • Check whether its URL is same-origin. For a remote image, verify that its server sends a compatible CORS response header.
  • Use useCORS: true only when the remote server permits access; otherwise arrange a suitable proxy or use an accessible asset.
  • Do not rely on allowTaint to make a canvas exportable.

The image looks blurry

Inspect the canvas’s actual pixel dimensions and the scale setting. A scale based on window.devicePixelRatio can improve high-DPI output, but it also increases the number of pixels the browser must allocate and process. Raise it only as needed and test on the browsers and devices your users use.

Long content is cut off

The html2canvas FAQ describes setting windowWidth and windowHeight to the element’s scroll dimensions as a way to address capture dimensions. For example, pass the element’s scrollWidth and scrollHeight as those option values when the goal is to capture its full content. Check the resulting layout: fixed and sticky elements can behave differently when the capture viewport changes.

The result is blank or partial

Canvas dimension and area limits vary with browser, operating system, hardware and available memory. Large captures can exceed a platform’s limits and produce blank or partial output without a useful error. There is no universal maximum that can safely be promised. Reduce the output size, lower scale, or capture separate sections and combine them in an appropriate workflow.

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

It works in the browser but not during server rendering

html2canvas relies on browser facilities such as window, document and computed styles. It is client-side, not a Node.js screenshot library. Run the capture after the component exists in the browser, or use browser automation such as Puppeteer or Playwright for server-side rendering.

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 your React page is publicly reachable by URL, ScreenshotNeo can capture that page through one GET request. This captures a website URL, not an unmounted or private in-memory component. For a URL-specific shot, set url to the page you want captured:

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

See the ScreenshotNeo API documentation for request options. Cookie banners, newsletter popups and chat widgets are removed before the shot; those cleanup steps can be turned off. Bot checks, blank pages, timeouts, failed loads and cache hits cost nothing, and response headers identify the page verdict and billing status. An MCP server provides take_screenshot, get_page_info and capture_pdf tools for AI agents and MCP clients.

The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. For a page URL rather than a local component, ScreenshotNeo is an alternative to setting up browser capture yourself. Sign up for 1,000 free screenshots a month—no card required.

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

Frequently Asked Questions

Can I convert a React component before it has rendered?

No. The DOM-based capture needs the browser-rendered element. Trigger capture only after that element is mounted and available through its ref.

Can I export a React component directly from Node.js with html2canvas?

No. html2canvas depends on browser APIs. For server-side screenshots, use a browser-automation approach such as Puppeteer or Playwright.

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.