Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
To let a visitor download a page section as a PDF without sending it to a conversion server, use html2pdf.js. It combines html2canvas, which reconstructs the selected DOM as a canvas, with jsPDF, which puts that output into a PDF. This works well for invoices, reports, and other controlled layouts, but it is a visual export—not a browser’s native, fully faithful print engine. The rendering limits of html2canvas, especially around unsupported CSS and cross-origin content, should shape your implementation.
Convert a DOM element to PDF
The example below exports an existing article element when the reader clicks a button. It uses html2pdf.js 0.10.1 from the CDN URL shown, letter paper, portrait orientation, half-inch margins, JPEG output at 0.95 quality, and a 2× canvas scale.
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js"></script>
<button id="download-pdf" type="button">Download PDF</button>
<article id="invoice">
<h1>Invoice</h1>
<p>Content to export.</p>
</article>
<script>
document.querySelector('#download-pdf').addEventListener('click', () => {
const element = document.querySelector('#invoice');
const options = {
margin: 0.5,
filename: 'invoice.pdf',
image: { type: 'jpeg', quality: 0.95 },
html2canvas: { scale: 2, useCORS: true },
jsPDF: { unit: 'in', format: 'letter', orientation: 'portrait' },
pagebreak: { mode: ['css', 'legacy'] }
};
html2pdf().set(options).from(element).save();
});
</script>
Place the script before the code that invokes html2pdf, as in the example. In a bundled application, install and import the library using the setup appropriate to your build system; the example here deliberately uses the browser CDN form. The button handler selects the element at click time, configures the export, and calls save() to initiate a download.
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Export the whole page instead
If the whole document is the intended export, the project also documents the concise call html2pdf(document.body). For a configured export, pass the desired element to the worker-style chain, such as html2pdf().from(element).set(options).save(). Exporting a specific container is usually easier to control than exporting document.body, because navigation, controls, and unrelated content otherwise become part of the output.
#1 Best Overall
What this pipeline renders—and what it does not
html2pdf.js does not simply ask the browser to print the DOM. html2canvas builds a representation from DOM information and draws it into a canvas; jsPDF then places that rendered result in a PDF. The output is therefore best understood as a visual rendering of a page section. Do not assume that every CSS property will appear exactly as it does on screen, or that the content will have all the structure and text behavior of a natively composed PDF.
html2canvas explicitly says that it does not take a literal screenshot: it renders properties it understands from DOM information. The result can differ when a layout relies on unsupported CSS or content the browser cannot expose to the page. Cross-origin images can also prevent a canvas from being read unless the browser permits access under the image server’s CORS policy. Setting useCORS: true requests the CORS path; it cannot grant permission that the remote server has not allowed.
- Good fit: a controlled invoice, report, card, or other DOM region whose appearance matters more than native PDF editing.
- Check first: custom fonts, remote images, charts, long tables, responsive layouts, and content that appears asynchronously.
- Different problem: creating or editing PDF objects, merging documents, or filling forms. For those tasks, consider a PDF-object library such as pdf-lib rather than treating arbitrary HTML as a PDF document.
Set paper size, layout, and page breaks
Choose the target paper size in jsPDF.format, set orientation to portrait or landscape, and specify margin. The example uses inches and letter paper; a report intended for A4 can use format: 'a4'. Keep the export width predictable: a responsive element may otherwise reflow at a different width than the one used for the on-screen layout.
Use html2pdf.js page-break modes alongside CSS break rules where sections, cards, or table rows should avoid splitting. The library documents the html2pdf__page-break class as an explicit break mechanism and supports CSS page-break properties through its page-break options. For example:
<style>
.report-section {
break-inside: avoid;
}
</style>
<section class="report-section">
<h2>Quarterly summary</h2>
<p>Keep this heading and its short summary together where possible.</p>
</section>
In the export options, pagebreak: { mode: ['css', 'legacy'] } enables the CSS and legacy handling used in the example. A CSS break rule is a request to the renderer, not a guarantee that a tall element will fit intact on one page. Test tables and sections at the paper size and margins that your users will actually download.
Use a print-specific layout when needed
If the export should omit screen controls or use a different layout, define print styles. The HTML2PDF API documentation describes using @media print rules as the print layout for PDF output.
@media print {
.screen-only { display: none; }
.report-section { break-inside: avoid; }
}
Keep the export styles intentional: hiding irrelevant controls and giving report sections a fixed width can make pagination easier to reason about than attempting to export an entire responsive application view.
Choose image quality and canvas scale deliberately
The image option controls the image type and quality used by the visual pipeline. The example uses JPEG at 0.95; choose an image type and quality that suit the content rather than assuming a single setting is best for every document. The html2canvas.scale option controls the rendering scale; the example uses 2 for a higher-resolution canvas than a 1× render. Higher scale can improve visual detail but creates a larger canvas, so long pages can consume substantial browser memory.
There is no reliable cross-browser speed, file-size, or fidelity benchmark established here. Measure the templates and browsers that matter to your own application instead of relying on a general performance percentage. In particular, a full-page canvas can become costly when the export includes large images or many pages.
Prepare content and assets before export
Start the export only when the content is ready. Wait for fonts, images, charts, and asynchronous data to finish loading; otherwise, the PDF may capture a fallback font, an empty chart, or a partially loaded image. If the page is assembled in stages, call the exporter after the application has completed those stages rather than merely after the click handler starts.
- Cross-origin images: prefer same-origin assets or serve remote assets with CORS headers that allow the page to load them.
useCORScannot override server headers or browser security rules. - Iframes: the html2canvas path cannot traverse cross-origin iframes because their documents are inaccessible. Same-origin iframes are supported, but test the result in your target browsers.
- Plugins and embedded content: treat plugin content and cross-origin iframe content as unsupported in this rendering path.
- Browser support: html2canvas lists modern evergreen browsers as its compatibility target. Validate your app’s actual browser matrix rather than inferring support for older or embedded browsers.
- Layout shifts: use a fixed export width and explicit margins so responsive breakpoints do not unexpectedly change the document composition.
Troubleshoot common export problems
An image is missing or the export fails around an image
Check whether the image is cross-origin and whether its server permits the required CORS access. Try a same-origin copy or configure the asset host’s CORS response. Keep useCORS: true only as a request for that path; it is not a workaround for a server that denies access.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Repair Windows errors before they cause bigger problems3Fix the driver behind crashes, sound loss and screen glitchesSome styling does not match the page
The export is reconstructed from DOM information, not captured as a literal browser screenshot. Identify CSS properties the renderer may not support and simplify the export stylesheet where exact output matters. A dedicated fixed-width export layout is often easier to control than a complex responsive screen design.
Rank #4
- Comprehensive Coverage: 130 carefully curated flashcards covering essential JavaScript concepts and syntax across 11 distinct sections for thorough learning
- Learning Progression: Structured content suitable for both beginners starting their coding journey and advanced programmers looking to reinforce their knowledge
- Practical Examples: Each card features real-world code examples and summaries to help understand and apply JavaScript concepts effectively
- Quick Reference: Concise and high-quality content designed for rapid learning and easy revision of JavaScript programming fundamentals
- Study Efficiency: Perfect learning tool for students, bootcamp participants, and self-taught programmers to master JavaScript concepts at their own pace
The PDF has blank or incomplete charts, fonts, or data
Make the export wait for asynchronous work to finish. Confirm that data rendering, image loading, and font loading are complete before calling html2pdf().from(element)...save(). If chart code updates the canvas after the export begins, the capture may happen too early.
A heading or table splits awkwardly across pages
Set the paper size and margins first, then use the page-break options and CSS break rules on the relevant sections. Test long tables at the target size; canvas-based rendering can produce page-break surprises, and a rule that keeps a short card together may not be sensible for a section taller than a page.
The output differs between screen widths
Make the export container’s width explicit and verify which responsive breakpoint is active during capture. A fluid layout can reflow columns or change text wrapping when the rendering width changes, which in turn shifts later page breaks.
Free tools Windows power users keep installed
One-click scans. No signup required.
When pdf-lib is a better fit
Use pdf-lib when you need to create pages, draw text or images, embed fonts, merge or split PDFs, or fill forms. Its documentation describes it as pure JavaScript with no native dependencies and usable in browsers, Node, Deno, and React Native. It works on PDF objects; it is not a drop-in way to reproduce arbitrary HTML and CSS. Choose based on the output you need: html2pdf.js for a visual export of a DOM region, pdf-lib for structured PDF creation or operations on PDF documents.
Best Value
Or skip the browser setup
If your input is a public webpage URL rather than an existing DOM element in the visitor’s browser, ScreenshotNeo can return a screenshot or PDF from one GET request. That is a different workflow from client-side conversion: it captures the URL, not a selector from your already-loaded page. See the ScreenshotNeo documentation for the API.
curl -G "https://api.screenshotneo.com/v1/shot"
-d access_key=YOUR_API_KEY
--data-urlencode url=https://stripe.com
-o shot.webp
The supplied request example saves an image as shot.webp; use the documented API options for the PDF output format. ScreenshotNeo removes cookie banners, newsletter popups, and chat widgets before capture, and bot checks, blank pages, and failed loads are never billed. Its MCP server lets AI agents take screenshots. The Free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots. Sign up for ScreenshotNeo’s free plan.
Decide based on the PDF you need
For a download button that turns a selected DOM element into a client-side PDF, start with html2pdf.js and build a fixed, export-friendly layout. Plan for a canvas-based rendering pipeline: wait for assets, control width and pagination, and verify cross-origin content in your target browsers. If the job is instead to generate PDF pages or manipulate PDF structures, use a PDF-object toolkit such as pdf-lib. If the source is a URL you want captured remotely, ScreenshotNeo offers a separate URL-to-capture workflow.
Crashes, 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 minuteWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallFrequently Asked Questions
Will the downloaded PDF text always be selectable?
Do not assume it will behave like a natively composed document: html2pdf.js uses a DOM-to-canvas visual pipeline. Check the generated file for your particular template and use case.
Can this method export a cross-origin iframe?
No. html2canvas cannot traverse a cross-origin iframe because the browser does not expose that document to the page.
Can I use this for an HTML fragment that is not currently in the DOM?
The documented workflow starts from an element or document. Put the content into a rendered element before exporting so the renderer has DOM content to process.
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.

