In Angular 2, call a TypeScript method from HTML with event binding: <button (click)="capture()">Save image</button>. Angular resolves capture() on the component instance. Inside that method, pass the target element to html2canvas, await the returned Promise, and download the resulting canvas as a PNG.
What the Angular 2 call actually does
Angular template statements run in the context of the component class. The (click) event binding listens for the browser click and invokes the named method, just as Angular’s user-input guide demonstrates with (click)="onClickMe()". You do not need to add a separate addEventListener for this button.
For a capture workflow, keep the template responsible for wiring the event and keep DOM access, asynchronous rendering, and file creation in the component method. This separation also makes the method reusable from other component code.
Install html2canvas and configure Angular 2
-
Install the package in the Angular project:
npm install @html2canvas/html2canvas -
Import the default export in the component. The documented TypeScript import is:
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Fix the driver behind crashes, sound loss and screen glitches3Repair Windows errors before they cause bigger problemsSpecial offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.#1 Best Overall
import html2canvas from '@html2canvas/html2canvas'; -
Make sure the code runs in a browser. html2canvas renders browser DOM and is not suitable for Node.js or server-side rendering.
Older Angular 2 applications may use a compiler or module configuration that differs from current Angular CLI projects. The essential requirements remain a TypeScript-compatible import and a browser bundle that includes the package.
Minimal working example
Template: bind the button and identify the target
<div #captureTarget class="receipt">
<h2>Order receipt</h2>
<p>Order #A-1048</p>
</div>
<button type="button" (click)="capture()">
Save image
</button>
#captureTarget is a template reference variable. It gives the component a precise element to render instead of capturing the entire document.
Component: use ViewChild and await html2canvas
import { Component, ElementRef, ViewChild } from '@angular/core';
import html2canvas from '@html2canvas/html2canvas';
@Component({
selector: 'app-receipt',
templateUrl: './receipt.component.html'
})
export class ReceiptComponent {
@ViewChild('captureTarget') captureTarget: ElementRef;
async capture(): Promise<void> {
const canvas = await html2canvas(this.captureTarget.nativeElement);
const link = document.createElement('a');
link.download = 'receipt.png';
link.href = canvas.toDataURL('image/png');
link.click();
}
}
html2canvas(element, options?) returns a Promise that resolves to a <canvas>. Awaiting it prevents the download code from running before rendering finishes. toDataURL('image/png') converts the canvas to a downloadable data URL, and the temporary anchor starts the browser download.
Rank #2
- HTML CSS Design and Build Web Sites
- Comes with secure packaging
- It can be a gift option
Passing the click event when you need it
Most capture buttons need no event argument. If you must inspect or prevent the native event, pass $event:
<button type="button" (click)="capture($event)">Save image</button>
capture(event: MouseEvent): void {
event.preventDefault();
// capture logic
}
Angular template reference variables and clean method arguments are generally preferable to reaching through an event’s target. For example, use #captureTarget and ViewChild when the target is known in the template.
Useful html2canvas options
The second argument controls rendering. Start with the default, then add only options required by your page:
const canvas = await html2canvas(this.captureTarget.nativeElement, {
backgroundColor: '#ffffff',
useCORS: true,
scale: window.devicePixelRatio
});
- backgroundColor: Set an explicit color when a transparent or inherited background would produce an unexpected result.
- useCORS: Requests CORS-enabled images. The image host must send an appropriate CORS header; this option cannot override a server policy.
- scale: Controls output pixel density. A larger value can improve sharpness but increases memory use and rendering time.
Consult the package’s documented options for additional controls such as viewport dimensions, logging, image timeout, and proxy configuration. Keep in mind that html2canvas reconstructs a visual representation from DOM and CSS; it does not take a screenshot of pixels produced by the operating system.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Rank #3
Cross-origin images and other browser limits
Why a canvas can become tainted
Images and other resources loaded from another origin can taint the canvas. Once tainted, browser security rules may prevent toDataURL() or similar pixel reads. Host images on the same origin, configure the image server for CORS, or use html2canvas’s proxy approach for cross-origin resources as described in its documentation.
What html2canvas cannot reproduce reliably
- Content blocked by the browser’s same-origin policy.
- Elements that depend on browser or operating-system chrome rather than page DOM.
- Animations or fonts that have not finished loading when capture begins.
- Very large pages that exceed available canvas memory.
For dynamic content, wait for the relevant data and fonts before enabling the capture button. You can also add a short application-level delay after your final state change.
Making the method production-ready
Prevent duplicate captures
Disable the button while rendering so a user cannot start several expensive canvas operations:
capturing = false;
async capture(): Promise<void> {
if (this.capturing) return;
this.capturing = true;
try {
const canvas = await html2canvas(this.captureTarget.nativeElement);
const link = document.createElement('a');
link.download = 'receipt.png';
link.href = canvas.toDataURL('image/png');
link.click();
} finally {
this.capturing = false;
}
}
<button type="button" [disabled]="capturing" (click)="capture()">
{{ capturing ? 'Rendering…' : 'Save image' }}
</button>
Handle failures visibly
Wrap the Promise in try…catch when a failed image load or a tainted canvas is possible. Show an actionable message rather than silently doing nothing:
Rank #4
- 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
errorMessage = '';
async capture(): Promise<void> {
this.errorMessage = '';
try {
const canvas = await html2canvas(this.captureTarget.nativeElement, { useCORS: true });
const link = document.createElement('a');
link.download = 'receipt.png';
link.href = canvas.toDataURL('image/png');
link.click();
} catch (error) {
this.errorMessage = 'The image could not be rendered. Check external images and try again.';
console.error(error);
}
}
Capture only after the view exists
ViewChild is available after Angular creates the view. A button rendered in the same template can be clicked only after that point, so the minimal example is safe. If you call capture() during initialization, wait until the view has initialized and verify that captureTarget is defined.
Debugging checklist
| Symptom | Likely cause | Fix |
|---|---|---|
capture is not a function or an Angular template error |
The method is missing, misspelled, or not on the component used by the template. | Check the component class name, method spelling, and the component attached to the template. |
Cannot read properties of undefined for nativeElement |
The template reference does not match, or capture ran before the view existed. | Use the exact #captureTarget name and call after view initialization. |
| Blank or incomplete image | Images, fonts, data, or animations were still loading. | Wait for rendering to finish, preload assets, pause animation, and capture again. |
SecurityError from toDataURL |
A cross-origin resource tainted the canvas. | Serve it with CORS, move it to the same origin, or configure a suitable proxy. |
| Import or module-resolution error | The package is not installed or the bundler cannot resolve the import. | Run npm install @html2canvas/html2canvas, then restart the development server and verify the documented import. |
| Slow tab or out-of-memory failure | The target is very large or the scale is excessive. | Capture a smaller element, reduce scale, and avoid repeated concurrent captures. |
Performance, quality, and accessibility
- Capture the smallest element that meets the requirement rather than
document.body. - Use a moderate scale; retina output is useful for print-like receipts but costs memory.
- Do not remove the visible button’s focus style or label. Keep the capture action keyboard-accessible.
- Provide an alternate text or downloadable data where an image is not sufficient for screen-reader users.
- Test in the browsers your Angular 2 application supports, especially when relying on CORS and download behavior.
Or skip the browser setup: ScreenshotNeo
If your requirement is a URL screenshot rather than an in-app DOM capture, ScreenshotNeo performs the capture through one HTTP request. It accepts cookie or consent banners as a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before the shot. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing status. Its MCP server exposes take_screenshot, get_page_info, and capture_pdf to Claude, Cursor, and other MCP clients.
Use the API documentation at https://screenshotneo.com/docs/ for authentication and options. A cURL request:
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}`);
ScreenshotNeo includes full-page and CSS-selector captures, lazy-image loading, dark mode, device presets or custom viewports, retina scale, PDF output, custom CSS and JavaScript, clicks, waits, request blocking, headers, cookies, user agents, authorization, timezone and geolocation, transparent backgrounds, resizing, configurable caching, signed image links, asynchronous jobs with signed webhooks, bulk capture of up to 100 URLs per call, a usage API, and an OpenAPI specification. Its parameter names are compatible with those used by other screenshot APIs, easing migration.
The Free plan includes 1,000 shots each month with no card. Paid plans start at $5 for 3,000 shots; Growth is $15 for 15,000, Pro $39 for 60,000, Scale $99 for 250,000, and Business $249 for 1,000,000. Yearly billing provides two months free, and every feature is available on every plan. Create a free ScreenshotNeo account to start with 1,000 screenshots a month and no card.
Best Value
When to choose each approach
- Use html2canvas when the Angular page itself must capture live component state, local styles, or unsaved user input without sending the URL to a service.
- Use ScreenshotNeo when you need repeatable URL-based captures, server-side automation, PDF output, popup and consent cleanup, or AI-agent integration.
Frequently Asked Questions
Can I call a component method without parentheses?
Use parentheses with the event binding, such as (click)="capture()". The parentheses tell Angular to execute the method when the event occurs.
Does html2canvas capture a remote website from Angular?
It captures DOM available in the current browser document. Cross-origin resources need same-origin access, CORS, or the documented proxy approach.
Can html2canvas run in an Angular server-rendered application?
The library runs in the browser. Invoke it only in browser-side code after the target element exists.
Recommended Free Tools
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.

