The practical answer: render the React element you want to export, attach a ref to it, wait for its images and fonts, call html2canvas, then download the returned canvas as a PNG. This works well for cards, invoices, charts, and other same-page components. It reconstructs the image from DOM and CSS rather than taking the browser’s native screenshot, so complex CSS, cross-origin assets, iframes, and very large canvases need special handling.
Choose the right kind of HTML-to-PNG conversion
There are two fundamentally different jobs:
- Client-side component export: the user’s browser turns a rendered React subtree into a canvas. This keeps data in the browser and needs no server, making it suitable for a download button.
- Browser-accurate or server-side capture: a real browser renders a URL or HTML document in an isolated environment. This is preferable for automated reports, social images, scheduled jobs, and pages that rely on browser behavior, but it requires browser operations or a managed service.
The example below uses @html2canvas/html2canvas, the package name shown in the current documentation. It is a DOM reconstruction library, not a native screenshot API. Its own documentation cautions that the result may not be 100% identical to the real representation because it builds the image from information available in the page.
Install html2canvas and create a capture component
Install the package with your preferred package manager:
npm install @html2canvas/html2canvas
yarn add @html2canvas/html2canvas
pnpm add @html2canvas/html2canvas
Then put a ref on the element that should become the PNG. The ref must point to an element that has already rendered and remains attached to the document while capture runs.
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →#1 Best Overall
- CRISP CLARITY: This 23.8″ Philips V line monitor delivers crisp Full HD 1920x1080 visuals. Enjoy movies, shows and videos with remarkable detail
- INCREDIBLE CONTRAST: The VA panel produces brighter whites and deeper blacks. You get true-to-life images and more gradients with 16.7 million colors
- THE PERFECT VIEW: The 178/178 degree extra wide viewing angle prevents the shifting of colors when viewed from an offset angle, so you always get consistent colors
- WORK SEAMLESSLY: This sleek monitor is virtually bezel-free on three sides, so the screen looks even bigger for the viewer. This minimalistic design also allows for seamless multi-monitor setups that enhance your workflow and boost productivity
- A BETTER READING EXPERIENCE: For busy office workers, EasyRead mode provides a more paper-like experience for when viewing lengthy documents
import { useRef, useState } from 'react';
import html2canvas from '@html2canvas/html2canvas';
export function CardExport() {
const captureRef = useRef(null);
const [busy, setBusy] = useState(false);
const [error, setError] = useState('');
async function downloadPng() {
const element = captureRef.current;
if (!element) return;
setBusy(true);
setError('');
try {
const canvas = await html2canvas(element, {
backgroundColor: null,
scale: window.devicePixelRatio,
useCORS: true,
});
const link = document.createElement('a');
link.download = 'card.png';
link.href = canvas.toDataURL('image/png');
link.click();
} catch (err) {
setError(err instanceof Error ? err.message : 'PNG export failed');
} finally {
setBusy(false);
}
}
return (
<>
Quarterly results
This rendered React subtree is exported.
{error && {error}
}
>
);
}
The API is asynchronous, so always await it. backgroundColor: null requests transparency where the element itself does not paint a background. scale controls output pixels; using the device pixel ratio produces a sharper export on high-density displays but also increases memory use. useCORS: true asks the browser to load eligible remote images with CORS. It cannot override a remote server’s policy.
Wait for images, fonts, and application data
Capture only after the component contains its final content. A button click usually gives React time to paint, but images may still be loading and data-driven components may still be changing. A small readiness helper can wait for images that are already in the captured subtree:
async function waitForImages(root) {
const images = Array.from(root.querySelectorAll('img'));
await Promise.all(images.map((img) => {
if (img.complete) return Promise.resolve();
return new Promise((resolve) => {
img.addEventListener('load', resolve, { once: true });
img.addEventListener('error', resolve, { once: true });
});
}));
}
async function downloadPng() {
const element = captureRef.current;
if (!element) return;
await waitForImages(element);
if (document.fonts?.ready) await document.fonts.ready;
const canvas = await html2canvas(element, {
backgroundColor: '#ffffff',
useCORS: true,
scale: Math.min(window.devicePixelRatio || 1, 2),
});
canvas.toBlob((blob) => {
if (!blob) throw new Error('The browser could not create a PNG blob');
const objectUrl = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = objectUrl;
link.download = 'card.png';
link.click();
URL.revokeObjectURL(objectUrl);
}, 'image/png');
}
The helper treats a failed image load as completion so one broken asset does not leave the export waiting forever. In production, also wait for the API request that supplies the component’s data and disable export while layout is changing.
Data URL or Blob: which download method should you use?
Data URL with toDataURL
canvas.toDataURL('image/png') is concise and matches the common official example. It creates a base64 string in memory and works well for small cards. The string can become expensive for large images.
Blob with toBlob
canvas.toBlob keeps binary output as a Blob and is generally a better choice for larger exports or code that uploads the file. Create an object URL for the download and revoke it after use. If your application needs to support browsers where the callback timing is inconvenient, wrap toBlob in a Promise.
Rank #2
- CRISP CLARITY: This 22 inch class (21.5″ viewable) Philips V line monitor delivers crisp Full HD 1920x1080 visuals. Enjoy movies, shows and videos with remarkable detail
- 100HZ FAST REFRESH RATE: 100Hz brings your favorite movies and video games to life. Stream, binge, and play effortlessly
- SMOOTH ACTION WITH ADAPTIVE-SYNC: Adaptive-Sync technology ensures fluid action sequences and rapid response time. Every frame will be rendered smoothly with crystal clarity and without stutter
- INCREDIBLE CONTRAST: The VA panel produces brighter whites and deeper blacks. You get true-to-life images and more gradients with 16.7 million colors
- THE PERFECT VIEW: The 178/178 degree extra wide viewing angle prevents the shifting of colors when viewed from an offset angle, so you always get consistent colors
function canvasToBlob(canvas) {
return new Promise((resolve, reject) => {
canvas.toBlob((blob) => {
if (blob) resolve(blob);
else reject(new Error('PNG encoding returned no Blob'));
}, 'image/png');
});
}
Control dimensions, crop, and appearance
The captured element’s layout determines the default width and height. Use the library’s options when you need a deliberate output:
- Scale: changes pixel density. A scale of 2 doubles each dimension and roughly quadruples the pixel count.
- Background: set a color for an opaque image or use
nullwhen transparency is wanted and no ancestor supplies a background. - Viewport and window dimensions: useful when exporting content that depends on viewport media queries or when a tall element is otherwise clipped. Set dimensions from the element’s scroll measurements where appropriate.
- Crop coordinates and size: use the documented crop options when only a region, rather than the whole element, should be exported.
- Device pixel ratio: the default scale is commonly the browser’s device pixel ratio; explicitly capping it can prevent unexpectedly huge files.
For a fixed-size social card, give the capture element explicit CSS dimensions and avoid responsive breakpoints changing during capture. Keep the element in the document; moving it into a detached fragment can prevent styles and layout information from being available.
Cross-origin images, fonts, and iframes
Images that disappear
Remote images must be served with headers that allow the requesting origin. useCORS enables an attempted CORS load, but it cannot make a server grant permission. Configure the image host to return an appropriate Access-Control-Allow-Origin value, or fetch the asset through a server-side proxy that you control and are authorized to use.
Security errors and tainted canvases
If unauthorized cross-origin pixels are drawn, the canvas becomes tainted. Reading it with toDataURL or toBlob can then throw a security error. The allowTaint option does not make readback safe; it permits drawing that may leave the canvas unusable for export. Fix the asset’s CORS response instead.
Cross-origin iframes
A page cannot read the document inside an iframe from another origin because of browser same-origin rules. The iframe’s contents will not be reconstructed as if they were part of your React tree. Render an equivalent component in your origin, obtain cooperation from the framed application, or use a real browser capture of the complete page.
Rank #3
- Clear visuals. Fluid motion: A 144Hz refresh rate and 1ms MPRT deliver smooth, tear‑free motion across work, gaming, and streaming for clearer, more fluid viewing.
- Eye comfort: TÜV Rheinland 3‑star* certification reduces harmful blue light while preserving stunning color quality without compromise. *TÜV Rheinland 3-star eye comfort certification.
- Wide viewing angle: Get consistent views across a wide 178° /178° viewing angle.
- In-Plane Switching (IPS): See excellent color accuracy and consistency across wide viewing angles with In-plane Switching (IPS) technology.
- Ultra-thin bezels: Maximize your viewing experience with thin bezels.
Fonts and SVG files
Fonts and SVG images also need to be accessible to the browser under normal loading and CORS rules. Wait for document.fonts.ready before capture when typography matters, and test the actual production asset URLs rather than assuming development behavior will match.
CSS fidelity: what html2canvas can and cannot promise
Because html2canvas interprets DOM and style information, unsupported or unusually implemented CSS can differ from the live page. Compare the PNG with the page for filters, blend modes, complex gradients, pseudo-elements, sticky or fixed positioning, masks, animations, and third-party widgets. Freeze animations, hide transient controls, and apply an export-only class when a stable design is more important than reproducing every interactive state.
This method is not a native browser screenshot. If pixel accuracy for an entire URL is a requirement, use a real browser renderer or a managed screenshot service instead of treating a DOM-to-canvas result as equivalent.
Large pages and browser limits
A canvas has finite width, height, and total-pixel limits that vary by browser and device. Very tall pages can produce blank, truncated, or failed output, especially when a high scale multiplies the dimensions. Reduce scale, capture sections and stitch them in a controlled workflow, or move the job to a server-side browser. Check the element’s scrollWidth and scrollHeight, and avoid allocating several full-size canvases at once.
For long reports, sectioned exports are usually more reliable than one enormous canvas. If the output is intended for printing, a PDF workflow may be more appropriate than a single PNG.
Troubleshooting checklist
The downloaded file is blank
- Confirm the ref is non-null and the element is attached to the document.
- Wait for data, images, and fonts before calling the capture function.
- Check that the element is not hidden with
display: noneor dependent on a collapsed ancestor. - Reduce dimensions or scale if the canvas exceeds a browser limit.
Some images are missing
- Inspect the image response for CORS headers.
- Use
useCORS: trueonly when the server is configured to allow it. - Replace unauthorized third-party assets with same-origin or proxied copies.
SecurityError occurs during export
One or more drawn pixels came from an unauthorized origin. Correct CORS or remove that asset. Do not rely on allowTaint if you need to read the PNG.
Rank #4
- CURVED FOR ENHANCED ENGAGEMENT: An immersive viewing experience with a curved monitor that wraps more closely around your field of vision; It creates a wider view, enhancing depth perception and minimizing peripheral distraction
- SMOOTH PERFORMANCE FOR SEAMLESS CONTENT: Stay in the action when playing games, watching videos, or working on creative projects; The 100Hz refresh rate reduces lag and motion blur so you don't miss a thing in fast-paced moments¹
- MORE GAMING POWER: Gain the edge with optimizable game settings; Color and image contrast can be adjusted to see scenes more vividly and spot enemies hiding in the dark; Game Mode adjusts any game to fill the screen so you can view every detail²
- KEEP IT EASY ON THE EYES: Care for your eyes and stay comfortable, even during long sessions; Advanced eye comfort technology certified by TÜV reduces eye strain by minimizing blue light and reducing irritating screen flicker²
- INCREASED VERSATILITY: Connect to more; Plug devices straight into your monitor for increased flexibility, making your computing environment even more convenient
The result looks different from the page
Check unsupported CSS, web-font readiness, media-query dimensions, animations, and browser-specific rendering. The library reconstructs rather than screenshots.
A cross-origin iframe is empty
Same-origin policy prevents the library from reading it. Capture an equivalent local component or use a real browser capture of the whole page.
The browser freezes
Lower scale, capture a smaller region, use toBlob, and avoid running multiple exports simultaneously. Large canvases consume substantial memory.
When a real browser or managed API is the better choice
Use browser automation or a hosted renderer when you need URL-level screenshots, scheduled server jobs, pages with cross-origin frames, consistent rendering independent of a user’s device, or browser behavior that DOM reconstruction cannot reproduce. Evaluate rendering fidelity, where execution occurs, access to fonts and assets, dimensions, privacy, operating cost, and failure handling.
Recommended Free Tools
A managed HTML-to-image service is also useful when your application should not maintain browser binaries, queues, retries, and workers. Confirm its authentication, retention, regional processing, limits, and pricing directly before sending sensitive HTML or user data.
Best Value
- 【INTEGRATED SPEAKERS】Whether you're at work or in the midst of an intense gaming session, our built-in speakers provide rich and seamless audio, all while keeping your desk clutter-free.
- 【EASY ON THE EYES】 Protect your eyes and enhance your comfort with Blue-Light Shift technology. This feature reduces harmful blue light emissions from your screen, helping to alleviate eye strain during long hours of use and promoting healthier viewing habits.
- 【WIDEN YOUR PERSPECTIVE】Our sleek minimal bezel design ensures undivided attention. The nearly bezel-free display seamlessly connects in a dual monitor arrangement, delivering an unobstructed view that lets you focus on more at once, completely distraction-free.
Or skip the browser setup
ScreenshotNeo provides a website screenshot API and MCP server. One GET request can return PNG, JPEG, WebP, or PDF, with options for full-page lazy-image loading, CSS-selector element capture, dark mode, device presets, retina scale, custom CSS and JavaScript, click and wait actions, request blocking, headers, cookies, user agents, authorization, timezone, geolocation, transparency, resizing, caching, signed links, asynchronous jobs, webhooks, bulk capture, usage data, and an OpenAPI specification.
It handles consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each step can be disabled. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing result. Its MCP server exposes take_screenshot, get_page_info, and capture_pdf to Claude, Cursor, and other MCP clients.
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 authentication and options. The same request in Python:
Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchPC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)
And in 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}`);
if (!res.ok) throw new Error(`Screenshot failed: ${res.status}`);
const image = Buffer.from(await res.arrayBuffer());
The Free plan includes 1,000 screenshots per month with no card. Starter is $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 included on every plan. Create a free ScreenshotNeo account to start.
Decision guide
| Requirement | Best fit | Reason |
|---|---|---|
| Download one React card in the user’s browser | html2canvas | No server is required and the ref targets exactly the component. |
| Large or repeated exports | Blob workflow or server renderer | Reduces base64 memory pressure and avoids client canvas limits. |
| Pixel-accurate full-page URL capture | Real browser or ScreenshotNeo | Native browser rendering handles page behavior that DOM reconstruction may miss. |
| AI-agent screenshot actions | ScreenshotNeo MCP server | Provides screenshot, page-info, and PDF tools through MCP. |
Frequently Asked Questions
Can I export only one child element instead of the whole React page?
Yes. Put the ref directly on the child element and pass that DOM node to html2canvas; only that subtree is reconstructed.
Does html2canvas capture a cross-origin iframe?
No. Browser same-origin restrictions prevent reading a document from another origin.
Should I use PNG or JPEG?
PNG preserves transparency and sharp text. Choose JPEG only when you control the output format and prefer a smaller, opaque photographic image.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Clear out junk files and repair common Windows errorsFree Scan →Can I upload the generated PNG instead of downloading it?
Yes. Convert the canvas to a Blob with toBlob, then append it to FormData or send it to your upload endpoint.
Quick Recap
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.

