The short version: install @html2canvas/html2canvas, import its default function, pass an HTMLElement, and await the returned HTMLCanvasElement. The rendering happens in the browser by rebuilding the element from its DOM and computed styles, so it is useful for many UI exports but is not the same as capturing the browser’s final pixels.
This guide shows a complete TypeScript implementation, explains sizing, transparency, cross-origin images, iframes and long pages, and gives fixes for the failures developers see most often.
What HTML2Canvas does—and what it does not do
HTML2Canvas runs in a web page and walks the target element’s DOM tree and computed styles to construct a canvas representation. It does not ask the browser for a native screenshot of already-composited pixels. CSS that the library does not support can therefore look different from the source page, even when the page itself renders correctly in Chrome, Firefox or Safari.
The API is browser-only: it relies on browser APIs and is not a Node.js server-rendering solution. The function accepts an HTMLElement and returns a Promise that resolves to an HTMLCanvasElement. Because the operation is asynchronous, use await inside an async function or handle the Promise with .then().
PC 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 & 11Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minute#1 Best Overall
Install the TypeScript package
For a new project, install the scoped package:
npm install @html2canvas/html2canvas
The scoped package includes its TypeScript declarations, so you do not need a separate @types installation. Older project material may show the unscoped package name; check your project’s dependency and import consistently rather than mixing package variants.
Minimal TypeScript example
Give the element a stable selector, verify that it exists, then await the capture:
import html2canvas from '@html2canvas/html2canvas';
async function captureCard(): Promise<void> {
const element = document.querySelector<HTMLElement>('#capture');
if (!element) {
throw new Error('Capture element not found');
}
const canvas = await html2canvas(element);
document.body.appendChild(canvas);
}
void captureCard();
Appending the canvas is only a demonstration. In an application you will usually convert it to a data URL, a Blob, or a downloadable file.
Download a PNG
import html2canvas from '@html2canvas/html2canvas';
async function downloadElement(selector: string): Promise<void> {
const element = document.querySelector<HTMLElement>(selector);
if (!element) throw new Error(`No element matched ${selector}`);
const canvas = await html2canvas(element);
const link = document.createElement('a');
link.download = 'capture.png';
link.href = canvas.toDataURL('image/png');
link.click();
}
void downloadElement('#capture');
Get a Blob for upload
async function canvasBlob(canvas: HTMLCanvasElement): Promise<Blob> {
return new Promise((resolve, reject) => {
canvas.toBlob(blob => {
if (blob) resolve(blob);
else reject(new Error('The browser could not create an image blob'));
}, 'image/png');
});
}
Call toBlob() before uploading to your server. If the canvas is tainted by a cross-origin image, both toDataURL() and toBlob() can fail; that is a browser security rule, not a TypeScript error.
Rank #2
- TypeScript implements a superset of syntax for strictly typed development, facilitating deep static analysis and enhanced development environment integration. The compiler translates source into standard script formats, ensuring parity across any runtime.
- TypeScript is ideal for front-end developers, full-stack engineers, and software architects who build large-scale web applications. It serves those looking to improve code excellence, reduce bugs through static checking, and maintain complex projects more.
- Lightweight, Classic fit, Double-needle sleeve and bottom hem
Options that matter in real applications
Pass an options object as the second argument. These controls affect appearance, output dimensions, scrolling and which content is included.
Background and pixel density
const canvas = await html2canvas(element, {
backgroundColor: null,
scale: window.devicePixelRatio,
});
backgroundColordefaults to white. Set it tonullfor a transparent background.scalecontrols the render scale. Its default is the browser’s device-pixel ratio. A larger value can make text sharper but increases memory use and canvas dimensions; a smaller value is safer for very large captures.
Viewport and cropping
width, height, x and y let you control the output size and crop region. windowWidth and windowHeight define the viewport dimensions used while rendering, which also affects media queries. scrollX and scrollY set the scroll position used for the render and are useful when fixed-position elements appear in the wrong place.
const cropped = await html2canvas(element, {
x: 24,
y: 16,
width: 800,
height: 450,
windowWidth: 1200,
windowHeight: 900,
scrollX: window.scrollX,
scrollY: window.scrollY,
});
Exclude controls and transient UI
You can ignore an element with the data-html2canvas-ignore attribute, or provide an ignoreElements predicate. The onclone callback is often the cleanest approach because it changes only the cloned document used for capture, not the live page.
const canvas = await html2canvas(element, {
onclone: clonedDocument => {
clonedDocument
.querySelector<HTMLElement>('.no-export')
?.setAttribute('data-html2canvas-ignore', 'true');
},
ignoreElements: candidate =>
candidate instanceof HTMLElement && candidate.matches('.debug-overlay'),
});
For static markup, this is equivalent:
<button class="no-export" data-html2canvas-ignore="true">Edit</button>
Images, loading and diagnostics
useCORS: trueasks the browser to request images with CORS enabled.proxyspecifies a proxy that retrieves an image and serves it in a same-origin-safe form when the image host cannot provide CORS headers.imageTimeoutcontrols how long image loading is allowed to wait.allowTaintdoes not bypass browser security. It can allow a tainted canvas to be produced, but the result may no longer be readable with export APIs.logging: trueenables diagnostic logging while you investigate missing resources or layout differences.
A production-oriented capture function
This example combines transparency, CORS, clone-time cleanup, an explicit timeout and an optional download:
import html2canvas from '@html2canvas/html2canvas';
export async function captureInvoice(): Promise<HTMLCanvasElement> {
const element = document.querySelector<HTMLElement>('#invoice');
if (!element) throw new Error('Invoice element not found');
const canvas = await html2canvas(element, {
backgroundColor: null,
scale: Math.min(window.devicePixelRatio, 2),
useCORS: true,
imageTimeout: 15000,
logging: false,
onclone: clonedDocument => {
clonedDocument.querySelectorAll<HTMLElement>('[data-live-only]')
.forEach(node => node.setAttribute('data-html2canvas-ignore', 'true'));
},
});
return canvas;
}
async function saveInvoice(): Promise<void> {
const canvas = await captureInvoice();
const blob = await new Promise<Blob>((resolve, reject) => {
canvas.toBlob(value => value ? resolve(value) : reject(new Error('PNG encoding failed')), 'image/png');
});
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = 'invoice.png';
link.click();
URL.revokeObjectURL(url);
}
void saveInvoice();
Cross-origin images and iframes
Why images disappear or taint the canvas
An image hosted on another origin is usable only when its server sends an appropriate Access-Control-Allow-Origin response header and the request is made in a CORS-compatible way. Set useCORS: true, but do not assume that option can fix a server that sends no CORS header. If you control the image host, configure it to allow your site’s origin (or an appropriate public origin) and ensure the image URL is stable.
When you cannot change the image host, configure the library’s proxy option to a service that fetches the image and returns it in a same-origin-safe form. A proxy must be designed carefully: validate allowed URLs, prevent server-side request forgery, enforce size limits and avoid exposing private network resources.
allowTaint is not a policy bypass. A tainted canvas may be displayed, but browser APIs that read pixels or encode the canvas can throw a security exception. For exports, solving CORS or proxying the asset is the reliable path.
Iframe boundaries
Same-origin iframes can be rendered recursively. Cross-origin iframes cannot be rendered because browser security prevents access to their contentDocument. Embedded plugin content such as Flash or Java applets is unsupported. If an embedded application must appear in an export, have that application produce its own image or expose a server-side rendering endpoint rather than trying to bypass the browser boundary.
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Fix clipped, blank or oversized captures
Long elements are cut off
For a tall element, match the virtual viewport to its scroll dimensions:
const canvas = await html2canvas(element, {
windowWidth: element.scrollWidth,
windowHeight: element.scrollHeight,
});
This is especially useful for dashboards and containers with internal scrolling. If the result is still clipped, reduce scale, set an explicit width or height, or capture several sections and combine them. Browsers impose maximum canvas dimensions; a page that is valid HTML can still exceed the bitmap size your browser can allocate.
Blank output
- Confirm the selector found the intended element and that it has non-zero dimensions.
- Wait until fonts, images and asynchronous data have loaded before calling HTML2Canvas.
- Enable
loggingand inspect the browser console. - Temporarily remove
display: none, clipping and transforms from ancestors to identify a layout cause. - Check for a cross-origin image that fails to load or taints the canvas.
Text or CSS looks different
Remember that this is a DOM reconstruction. Unsupported CSS, complex filters, blend modes, pseudo-element interactions or browser-specific rendering can differ. Simplify the export stylesheet, set explicit dimensions and colors, and use onclone to apply export-only styles. If pixel fidelity to the browser’s final compositor is mandatory, use a browser automation screenshot service instead of a DOM-to-canvas reconstruction.
Performance, reliability and security checklist
- Capture only what you need. A focused element is faster and less likely to hit canvas limits than the entire document.
- Control scale. Device-pixel-ratio rendering improves sharpness but multiplies memory use in both dimensions.
- Wait deliberately. Trigger capture after data, web fonts and images are ready; do not rely on an arbitrary short delay when you can observe a real readiness condition.
- Keep the UI responsive. Large DOM trees and high-resolution canvases can consume substantial main-thread time. Consider a “Preparing image…” state and avoid capturing repeatedly on every keystroke.
- Protect proxy endpoints. Restrict destinations, cap response sizes and timeouts, and block internal IP ranges.
- Test each target browser. Evergreen browsers support the core approach, but CSS differences and maximum canvas dimensions vary by browser and device.
- Release resources. Revoke object URLs after downloads and discard canvases that are no longer needed.
Or skip the browser setup
If you need a screenshot of a URL rather than a canvas reconstructed inside your own page, ScreenshotNeo provides a single HTTP request and handles browser capture for you. Its cleanup step accepts cookie or consent banners and removes more than 60 known consent platforms, newsletter popups and chat widgets before the shot; each step can be disabled. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and response headers identify the page verdict and billing status.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
cURL:
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}`);
See the parameter reference and additional options in the ScreenshotNeo documentation. It supports full-page captures with lazy images loaded, CSS-selector element captures, dark mode, device presets or custom viewports, retina scale, PDF output, custom CSS and JavaScript, clicks, wait conditions, 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 of up to 100 URLs per call, a usage API and an OpenAPI specification. Existing parameter names used by other screenshot APIs also work, which can simplify migration. An MCP server exposes take_screenshot, get_page_info and capture_pdf to Claude, Cursor and other MCP clients, so AI agents can request captures directly.
Best Value
The Free plan includes 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 shots; yearly billing gives two months free, and every feature is available on every plan. Create a free ScreenshotNeo account to try it without a card.
When to choose HTML2Canvas
Choose HTML2Canvas when the capture must happen in the user’s browser, the source is already a live DOM element, and you need client-side control over crop, scale, transparency or cloned export-only content. Choose a browser screenshot service when you need a URL captured outside the user’s session, native browser pixels, cross-origin pages, repeatable server-side jobs or automation without shipping a capture workflow to every client.
Frequently Asked Questions
Does HTML2Canvas create a real screenshot file by itself?
It creates an HTMLCanvasElement. You must call a canvas export method such as toDataURL() or toBlob() to obtain an image representation.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Clear out junk files and repair common Windows errors3Fix the driver behind crashes, sound loss and screen glitchesDo I need @types/html2canvas?
The scoped @html2canvas/html2canvas package includes TypeScript declarations, so a separate @types package is not required.
Can HTML2Canvas run in a Node.js API route?
Not directly. It depends on browser APIs and a live DOM; use a browser automation or server screenshot service for server-side rendering.
Why does useCORS: true still leave an image missing?
The image server must return a compatible Access-Control-Allow-Origin header. If it does not, configure the server or use a carefully secured image proxy.
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.




