How to Use jsPDF addHTML in Angular 4
Learn how Angular 4 can export a component to PDF with legacy jsPDF addHTML, why it may be missing, and how to migrate to jsPDF's html() API.

Direct answer: In a legacy Angular 4 app, get the rendered element with @ViewChild, load a jsPDF build that still includes the deprecated addHTML plugin plus html2canvas (or rasterizeHTML), then call addHTML after Angular has rendered the view. Its callback runs after rendering, so save the PDF there. For maintained code, use jsPDF’s html() method instead: jsPDF 1.4.2 release notes say the project will no longer support fromHTML and addHTML, and identify 1.4.1 as the stable choice if old plugins must be retained. jsPDF 1.4.2 release notes.
This guide covers the legacy Angular 4 wiring, the errors most likely to arise, and the migration path. Exact imports and plugin availability depend on your Angular CLI, TypeScript, module format, and pinned jsPDF build; treat legacy code as a pattern to adapt and verify against that build’s API documentation. jsPDF generated API documentation.
1. Understand what addHTML does
addHTML is a legacy rasterizing plugin method. It renders a DOM element through html2canvas or rasterizeHTML, places the rendered result in a PDF, and signals completion through a callback. The renderer works asynchronously. The old API documents the signature as addHTML(element, x, y, options, callback), with overloads for coordinates and options. addHTML API documentation.

This is not the same as laying out each HTML element as selectable PDF text. Because the content is rasterized, the result behaves like an image on the page: visual fidelity depends on browser rendering and canvas constraints, and text may not be searchable or selectable in the same way as text written directly into a PDF.
2. Prepare the Angular 4 project
- Check the existing dependency versions. Inspect
package.jsonand the lockfile before changing packages. Angular 4 projects commonly have older TypeScript and bundler constraints; do not install an arbitrary current jsPDF release into a legacy application and assume the imports will work. - Choose the intended path. If you must retain
addHTML, use the legacy build appropriate to the app. The jsPDF release notes say 1.4.1 remains the stable choice when old plugins must be used. Pin related versions in the lockfile. This pinning advice is an engineering precaution inferred from the stated end of support, not a guarantee of compatibility. - Include a renderer. The plugin needs
html2canvasorrasterizeHTML. The plugin throws if neither renderer is available. Check the specific legacy build’s loading instructions and make sure the module you load is the one the plugin can see. - Build the target as normal visible page content. Put the export region in the component template and ensure it has dimensions. Call the capture only after the view exists, and wait for its images and fonts when they matter to the result.
3. Legacy Angular 4 example using addHTML
This representative TypeScript pattern gets an element reference after view initialization and saves from the completion callback. The import syntax may need adjustment for the project’s module setup and pinned jsPDF distribution.
import { AfterViewInit, Component, ElementRef, ViewChild } from '@angular/core';
import * as jsPDF from 'jspdf';
import 'jspdf/dist/jspdf.min.js';
import 'html2canvas';
@Component({
selector: 'app-report',
template: `
<section #pdfContent class="report">
<h1>Monthly report</h1>
<p>Revenue and account summary.</p>
</section>
<button type="button" (click)="exportPdf()">Download PDF</button>
`
})
export class ReportComponent implements AfterViewInit {
@ViewChild('pdfContent') pdfContent: ElementRef;
private viewReady = false;
ngAfterViewInit(): void {
this.viewReady = true;
}
exportPdf(): void {
if (!this.viewReady || !this.pdfContent) {
return;
}
const doc: any = new (jsPDF as any)('p', 'mm', 'a4');
const element = this.pdfContent.nativeElement;
doc.addHTML(element, {}, () => {
doc.save('monthly-report.pdf');
});
}
}
The button can only be clicked after the view is initialized in normal use, but the guard also makes the precondition explicit. Some old builds expose a different constructor or overload shape. If the compiler rejects this import or invocation, inspect the installed package’s declarations and distribution files rather than silently mixing examples from different jsPDF generations.
Wait for content before capturing
ngAfterViewInit means Angular has initialized the component view; it does not guarantee that asynchronous data, remote images, or web fonts are ready. If the report is populated asynchronously, disable export until the data is present. For images, wait for their load events. For custom fonts, wait for the browser’s font readiness where supported. Keep the target visible: rendering a hidden element or an element with zero width or height can produce blank or clipped output.
4. Coordinates, options, and page layout
The legacy API accepts an element, optional x/y coordinates, options, and a callback. Its documented options cover dimensions, margins, format, compression, and page handling; the precise option names and behavior are build-specific, so use the documentation corresponding to the pinned legacy package. Do not copy option names from a current html() example into addHTML without checking.
| Decision | What to consider |
|---|---|
| Page orientation | Choose portrait or landscape when constructing the PDF; landscape can suit wide tables. |
| Page size and units | Choose the document format and units intentionally. A4 in millimeters is shown above; the element’s CSS pixels still need to be rendered and scaled into the PDF page. |
| Position and margins | Use x/y and supported margin settings to keep the rendered region inside the printable area. |
| Large content | Check the legacy page-handling options for your version. A tall raster image may be scaled, clipped, or split in ways that differ from semantic document pagination. |
| Compression | Where the build exposes compression options, balance file size against image quality and rendering time. |
For long reports, structure content into page-sized sections if the legacy plugin’s automatic page behavior does not match the required layout. Raster output can make fine text hard to read when scaled down. Test the actual document at its intended print size and check page boundaries, not just the first screenful.
5. Why addHTML is undefined, and the supported direction
addHTML is not a function usually means the loaded jsPDF object does not contain the legacy plugin, or the module/bundle loading order does not expose it. The name was deprecated and later builds may omit it. The 1.4.2 release notes state: “We will not support any longer fromHTML and addHTML.” They introduce the newer html method, based on html2canvas and the context2d module. Release notes.
If the project can move away from the legacy method, migrate to doc.html(...) and use the import form documented for the installed jsPDF version. Current jsPDF documentation shows a TypeScript import and explains that html() dynamically loads html2canvas; when the input is an HTML string, dompurify is also used. jsPDF html() documentation.
import { jsPDF } from 'jspdf';
exportPdf(): void {
const element = this.pdfContent.nativeElement;
const doc = new jsPDF({ orientation: 'portrait', unit: 'mm', format: 'a4' });
doc.html(element, {
callback: (finishedDoc) => finishedDoc.save('monthly-report.pdf')
});
}
Here too, saving belongs in the callback: the HTML rendering is asynchronous. Current documentation describes TypeScript imports and notes Angular projects may configure externals with custom webpack builders. That setup is relevant only when your build configuration requires it; do not add a custom builder without first identifying a concrete bundling issue. jsPDF HTML module documentation.
6. Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
addHTML is not a function |
The loaded build omits the deprecated plugin, or the import/module format does not expose it. | Confirm the exact installed jsPDF version and bundle; use the legacy build that contains the plugin, verify loading order and renderer availability, or migrate to html(). |
| PDF is blank | Capture ran before Angular rendered the view, target is hidden, or it has no dimensions. | Call after view initialization and after async data is ready; verify visibility, width, and height in the browser. |
| Only part of the page appears | Content exceeds expected dimensions or legacy page handling/scaling differs from the layout. | Check the target’s measured size, PDF format, x/y, scaling and pagination options. Try explicit page-sized sections for long reports. |
| Images are missing | Remote resources may be blocked by browser canvas security or fail to load before rendering. | Wait for image loading and inspect the renderer’s cross-origin/resource constraints. Use accessible assets and test cross-origin sources in the target browser. |
| Callback does not run | No renderer is available, or the callback was passed in an overload that the pinned build interprets differently. | Ensure html2canvas or rasterizeHTML is loaded and compare the call signature to that build’s API docs. The legacy plugin requires one of these renderers. |
| Text is fuzzy or file is large | The HTML is rasterized at a scale that does not suit the document dimensions. | Review supported rendering scale and compression options, avoid shrinking a very wide capture onto a small page, and inspect at print size. |
| Styles differ from the page | Only browser-applied styles and resources available to the renderer are captured; print-specific expectations may not match screen CSS. | Use a dedicated export stylesheet, ensure fonts and assets are ready, and capture the visible rendered element rather than an unrendered template. |
7. Performance, reliability, and cost
DOM-to-PDF rendering uses browser work to rasterize the element, then embeds that output. Bigger DOM trees, large images, and high pixel density generally require more memory and time; this is a practical engineering inference, not a benchmark. Keep export regions focused, avoid needlessly huge images, and prevent multiple simultaneous exports from one component. If the app can be closed or navigated away during generation, keep the UI state clear and only report completion after the callback runs.
For reliability, pin legacy dependencies, test the exact production bundle, and cover representative content: short text, long tables, images, custom fonts, and a multi-page report. Angular 4 and the old jsPDF integration are maintenance constraints; no universal compatibility guarantee follows from a version number alone. If PDF output is business-critical, plan a migration or server-side document path with explicit layout tests.
Client-side generation has no per-request screenshot service charge, but it consumes the user’s browser time and device resources. The operational cost is maintenance: keeping old package combinations buildable and debugging browser-specific rendering differences. There are no authoritative performance or reliability statistics for this Angular 4/addHTML combination in the research sources.
8. Or skip the browser setup
If your goal is to capture a website as an image or PDF rather than export an Angular component’s live DOM, ScreenshotNeo provides a screenshot API and MCP server. One GET request returns PNG, JPEG, WebP, or PDF. See the API documentation.

curl -G "https://api.screenshotneo.com/v1/shot" \
-d access_key=YOUR_API_KEY \
--data-urlencode url=https://stripe.com \
-o shot.webp
Cookie banners, newsletter popups, and chat widgets are removed before the shot; each cleanup step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers say which page verdict and billing outcome applied. An MCP server lets AI agents use take_screenshot, get_page_info, and capture_pdf. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. This captures a URL, not an Angular component’s in-memory DOM. Sign up for 1,000 free screenshots a month, no card required.
9. Short FAQ
Can I use addHTML with any current jsPDF release?
No. It is deprecated, and releases after the legacy period may not include it. Check the exact package and use the maintained html() path where possible.
Does addHTML produce selectable PDF text?
It rasterizes HTML through a renderer and adds the rendered result. Expect image-like output rather than semantic PDF text.
Can I export a component before it appears on screen?
Capture requires a rendered element with usable dimensions. Wait until Angular has created and populated the view, then ensure it is visible to the renderer.
Should a new Angular project use Angular 4 and addHTML?
No. The method is legacy and jsPDF has moved toward html(). Use current supported dependencies for a new project.


