Recommended Free Tools
Use a DOM-to-canvas pipeline, set an explicit capture scale, wait for fonts and images, and paginate the result deliberately. For most React components, the practical client-side stack is html2canvas plus jsPDF; html2pdf.js packages the same approach with page-break options. If your component library offers a semantic PDF exporter, use that instead when selectable text, table structure, and reliable pagination matter more than pixel-level CSS reproduction.
Choose the export path first
Your choice determines sharpness, text behavior, CSS fidelity, and how much pagination code you must maintain.
| Approach | Best for | Output and trade-offs |
|---|---|---|
| html2canvas + jsPDF | Arbitrary React components with custom CSS | Flexible visual capture; the canvas is placed as a raster image in the PDF, so text is generally not selectable. Unsupported CSS, cross-origin images, and iframes can differ from the browser. |
| html2pdf.js | A packaged element-to-PDF workflow | Short setup with filename, image quality, jsPDF settings, and CSS or legacy page-break modes. Automatic pagination still needs inspection at page seams. |
| Structured component exporter | Supported grids and UI libraries | Semantic rows and columns, selectable text, and library-aware pagination. For example, DevExtreme’s React PDF exporter uses exportDataGrid and requires jsPDF 2.3.1 or later. |
Build a sharp export with html2canvas and jsPDF
1. Install the packages
npm install html2canvas jspdf
The code below captures a component referenced with useRef, waits for browser assets, renders at a deliberate scale, and adds proportional pages to a PDF.
2. Give the export target a stable print layout
Use a dedicated wrapper rather than capturing an element whose size changes with a sidebar or responsive breakpoint. Set an explicit width, background, padding, and text color for the export state. This prevents transparent backgrounds, clipped shadows, and layout changes caused by the viewport.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
#1 Best Overall
- PORTABLE SCANNER FOR USE ON-THE-GO — The fastest and lightest mobile single-sheet-fed compact document scanner in its class¹
- QUICK DOCUMENT SCANNING ― This Epson ultra-fast scanner scans a single page as quickly as 5.5 seconds²; Windows and Mac compatible
- VERSATILE PAPER HANDLING ― Portable scanner scans documents up to 8.5 x 72 in; Also easily digitizes receipts and ID cards to make accounting, bookkeeping, and organizing simpler
- INTUITIVE, HIGH-SPEED SOFTWARE — Epson ScanSmart Software³ is a smart tool allowing you to easily scan, review, and save; Stay organized easily with the help of this Epson scanner
- EASY SETUP — USB-powered connect to your computer for quick and simple scanning; No batteries or external power supply required to operate portable document scanner; Standard Connectivity: USB 2.0
import React, { useRef, useState } from 'react';
import html2canvas from 'html2canvas';
import { jsPDF } from 'jspdf';
export default function Report() {
const reportRef = useRef(null);
const [exporting, setExporting] = useState(false);
async function exportPdf() {
const element = reportRef.current;
if (!element) return;
setExporting(true);
try {
await document.fonts?.ready;
const images = Array.from(element.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 });
});
}));
const scale = Math.max(2, window.devicePixelRatio || 1);
const canvas = await html2canvas(element, {
scale,
useCORS: true,
backgroundColor: '#ffffff',
imageSmoothingEnabled: true,
width: element.scrollWidth,
height: element.scrollHeight,
windowWidth: element.scrollWidth,
windowHeight: element.scrollHeight
});
const pdf = new jsPDF({ unit: 'mm', format: 'a4', orientation: 'portrait' });
const pageWidth = pdf.internal.pageSize.getWidth();
const pageHeight = pdf.internal.pageSize.getHeight();
const margin = 10;
const imageWidth = pageWidth - margin * 2;
const imageHeight = canvas.height * imageWidth / canvas.width;
const printableHeight = pageHeight - margin * 2;
const pixelsPerPage = Math.floor(canvas.width * printableHeight / imageWidth);
let offset = 0;
let page = 0;
while (offset < canvas.height) {
const sliceHeight = Math.min(pixelsPerPage, canvas.height - offset);
const slice = document.createElement('canvas');
slice.width = canvas.width;
slice.height = sliceHeight;
slice.getContext('2d').drawImage(
canvas, 0, offset, canvas.width, sliceHeight,
0, 0, canvas.width, sliceHeight
);
if (page > 0) pdf.addPage();
const slicePdfHeight = slice.height * imageWidth / slice.width;
pdf.addImage(slice, 'PNG', margin, margin, imageWidth, slicePdfHeight);
offset += sliceHeight;
page += 1;
}
pdf.save('react-component.pdf');
} finally {
setExporting(false);
}
}
return (
<>
<button onClick={exportPdf} disabled={exporting}>
{exporting ? 'Preparing PDF…' : 'Export PDF'}
</button>
<section ref={reportRef} className="report-export">…your component…</section>
</>
);
}
The slice loop avoids trying to place one very tall canvas on a single page. It computes the image width from the PDF’s printable width, then derives every slice’s height from the canvas aspect ratio, so the component is not stretched.
3. Tune resolution without exhausting memory
scale controls the canvas’s internal pixel density. html2canvas defaults it to window.devicePixelRatio; starting at that value (or at 2 for consistent output) is usually safer than choosing an arbitrarily large number. A larger scale multiplies the raster surface in both dimensions, increasing memory use and PDF size. Test the largest component you actually export, not just a small sample.
- Start with
Math.max(2, window.devicePixelRatio || 1). - Reduce the scale for very tall dashboards or mobile browsers that run out of memory.
- Keep the PDF page format, margins, and orientation explicit.
- Inspect small text, SVGs, gradients, shadows, and chart labels at 100% in a PDF viewer.
Wait for fonts, images, and dynamic content
Capturing immediately after a React render can produce fallback fonts, blank images, or a chart that has not finished drawing. Await document.fonts.ready, resolve image load events, and only then call html2canvas. If content appears after an API request, expose an isReady state and enable the export button only after the data and visualizations are complete.
For lazy-loaded images, scroll or otherwise trigger loading before capture, or render an export-only version in which all required images are mounted. Give the export wrapper a background color even if the on-screen design is transparent.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Scan for outdated or missing drivers - takes under a minuteDriver Scan →Rank #2
- FAST SPEEDS - Scans color and black and white documents a blazing speed up to 16ppm (1). Color scanning won’t slow you down as the color scan speed is the same as the black and white scan speed.
- ULTRA COMPACT – At less than 1 foot in length and only about 1. 5lbs in weight you can fit this device virtually anywhere (a bag, a purse, even a pocket).
- READY WHENEVER YOU ARE – The DS-640 mobile scanner is powered via an included micro USB 3. 0 cable allowing you to use it even where there is no outlet available. Plug it into you PC or laptop and you are ready to scan.
- WORKS YOUR WAY – Use the Brother free iPrint&Scan desktop app for scanning to multiple “Scan-to” destinations like PC, Network, cloud services, Email and OCR. (2) Supports Windows, Mac and Linux and TWAIN/WIA for PC/ICA for Mac/SANE drivers. (3)
- OPTIMIZE IMAGES AND TEXT – Automatic color detection/adjustment, image rotation (PC only), bleed through prevention/background removal, text enhancement, color drop to enhance scans. Software suite includes document management and OCR software. (4)
Handle cross-origin images and browser security
Set useCORS: true when image servers send an appropriate Access-Control-Allow-Origin response. The image URL must be reachable with CORS headers; adding the option alone cannot override the browser’s same-origin policy. When you control neither server, use a same-origin proxy that fetches and serves the asset with correct headers, subject to that service’s terms.
Cross-origin iframes are a separate limitation: browser security prevents html2canvas from reading another origin’s document. Capture content you own inside the parent page, use an export endpoint from the iframe provider, or omit the iframe and show a clearly labeled placeholder. Do not attempt to bypass this restriction with client-side JavaScript.
Use html2pdf.js when automatic pagination is acceptable
html2pdf.js wraps html2canvas and jsPDF and is convenient for a button-driven export. Install it with:
npm install html2pdf.js
import html2pdf from 'html2pdf.js';
function saveElement(element) {
const options = {
margin: 0.25,
filename: 'component.pdf',
image: { type: 'jpeg', quality: 0.98 },
html2canvas: {
scale: Math.max(2, window.devicePixelRatio || 1),
useCORS: true
},
jsPDF: { unit: 'in', format: 'letter', orientation: 'portrait' },
pagebreak: { mode: ['css', 'legacy'] }
};
return html2pdf().set(options).from(element).save();
}
Add CSS page-break rules to keep logical blocks together:
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Rank #3
- FAST DOCUMENT SCANNING — Document scanner with feeder allows you to speed through stacks with a 50-sheet Auto Document Feeder (ADF); Efficient office scanner to help you scan more productively
- INTUITIVE, HIGH-SPEED SOFTWARE — Quickly scan with this desktop document scanner; Epson ScanSmart Software lets you easily preview scans, email files, upload to the cloud, and more; Plus, automatic file naming saves even more time
- SEAMLESS INTEGRATION — Easily incorporate your data into most document management software with the included TWAIN driver; Office document scanner integrates seamlessly with business workflows
- EASY SHARING — Duplex scanner allows you to scan straight to email or popular cloud storage2 services like Dropbox, Evernote, Google Drive, and OneDrive for simple storage and sharing
- SIMPLE FILE MANAGEMENT — Scanner allows the creation of searchable PDFs with Optical Character Recognition (OCR) and convert scans to editable Word or Excel files effortlessly; Designed for home and office document scanning
.report-card { break-inside: avoid; page-break-inside: avoid; }
.page-start { break-before: page; page-break-before: always; }
Automatic page breaking is not a guarantee that headings, cards, or table rows will land where you expect. Render representative long content and inspect every boundary. If exact placement matters, use the explicit canvas-slicing approach instead.
When a semantic exporter is the better answer
A DOM screenshot is fundamentally a raster image in a PDF. It is the right trade-off for visual fidelity across custom CSS, but it does not preserve a document model. If users must search, select, copy, or reflow text, prefer a structured PDF renderer. DevExtreme’s documented React exporter, for example, provides exportDataGrid for supported grids and returns a promise-like result; it requires jsPDF 2.3.1 or later. The trade-off is that library-specific exporters cover their supported components rather than arbitrary DOM and CSS.
Pagination patterns for long components
Canvas slicing
Capture once, then copy vertical regions into one PDF page at a time, as in the first example. This preserves the rendered appearance and works for dashboards, invoices, and reports that exceed one page.
Logical page sections
Render each report section as a page-sized element and call addImage once per section. This gives you control over headers, footers, and deliberate breaks, but requires the component to know its print structure.
Rank #4
- Scanner type: Document
- Connectivity technology: USB
- With Auto Scan Mode, the scanner automatically detects what you're scanning
- Digitize documents and images
CSS-driven breaks
Use break-before, break-after, and break-inside with html2pdf.js. This is fastest to implement, but browser-to-PDF layout can still split content unexpectedly; always test the longest realistic data set.
Troubleshoot blurry, blank, or incorrect PDFs
| Symptom | Likely cause | Fix |
|---|---|---|
| Text looks soft | Low canvas scale or an oversized image later downsampled | Start at device-pixel ratio or 2, keep page geometry explicit, and avoid scaling the PDF image beyond its calculated dimensions. |
| Right or bottom content is missing | Capture used viewport dimensions instead of the element’s full scroll size | Pass scrollWidth, scrollHeight, and matching windowWidth/windowHeight. |
| Images are blank or throw a tainted-canvas error | Cross-origin response lacks CORS headers | Configure Access-Control-Allow-Origin, use useCORS, or proxy the asset through your origin. |
| Web fonts are replaced | Capture ran before fonts finished loading | Await document.fonts.ready and verify the font files load successfully. |
| An iframe is empty | It is cross-origin | Use an export API from the iframe owner or omit that content; the browser will not expose the document to html2canvas. |
| Browser tab crashes | The scaled canvas is too large for available memory | Lower scale, capture sections separately, reduce huge images, or move rendering to a server-side workflow. |
| Pages split awkwardly | Automatic pagination has no knowledge of your component’s logical blocks | Add CSS break rules, use page-sized sections, or slice the canvas at deliberate boundaries. |
| PDF differs from the live page | html2canvas reconstructs supported DOM/CSS rather than taking a literal browser screenshot | Simplify export CSS, test unsupported effects, and choose a structured exporter when exact document semantics are required. |
Performance, reliability, and security notes
- Capture only the export wrapper, not the entire application shell.
- Hide animations, blinking cursors, hover menus, ads, and transient notifications in an export-specific stylesheet.
- Use a deterministic locale, timezone, and data snapshot so repeated exports are comparable.
- Do not put secrets in custom client-side headers or expose private image URLs solely for capture.
- For very large reports, generate pages incrementally or use a server-side browser/PDF service to avoid mobile memory limits.
- Keep a visual regression sample containing fonts, SVG, gradients, shadows, charts, lazy images, and a multi-page table.
Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server for developers. One request returns a PNG, JPEG, WebP, or PDF, while its capture flow accepts cookie and consent banners 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; response headers identify the page verdict and whether it was billed.
For a PDF or image of a public React route, call the API directly (see the ScreenshotNeo documentation for all options):
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
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)
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 also supports full-page captures with lazy images loaded, CSS-selector element capture, dark mode, 12 device presets plus custom viewports, retina scale, PDF paper size/margins/landscape/page ranges, HTML/CSS-to-image, custom CSS and JavaScript, pre-capture clicks, hidden selectors, waits for selectors/delays/network idle, request and resource blocking, custom headers/cookies/user agents/Authorization, timezone and geolocation, transparent backgrounds, resizing, selectable 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. Parameter names used by other screenshot APIs also work.
The free plan includes 1,000 shots each month with no card. Paid plans start at $5 for 3,000 shots; every feature is included on every plan. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. Create a free ScreenshotNeo account to start.
Best Value
- OUR MOST ADVANCED SCANSNAP. Large touchscreen, fast 45ppm double-sided scanning, 100-sheet document feeder, Wi-Fi and USB connectivity, automatic optimizations, and support for cloud services. Upgraded replacement for the discontinued iX1600
- CUSTOMIZABLE. SHARABLE. Select personalized profiles from the touchscreen. Send to PC, Mac, mobile devices, and clouds. QUICK MENU lets you quickly scan-drag-drop to your favorite computer apps
- STABLE WIRELESS OR USB CONNECTION. Built-in Wi-Fi 6 for the fastest and most secure scanning. Connect to smart devices or cloud services without a computer. USB-C connection also available
- PHOTO AND DOCUMENT ORGANIZATION MADE EFFORTLESS. Easily manage, edit, and use scanned data from documents, receipts, photos, and business cards. Automatically optimize, name, and sort files
- AVOIDS PAPER JAMS AND DAMAGE. Features a brake roller system to feed paper smoothly, a multi-feed sensor that detects pages stuck together, and skew detection to prevent paper damage and data loss
FAQ
Will this produce selectable text?
Not with the html2canvas-plus-jsPDF pipeline: it places a raster canvas into the PDF. Use a structured exporter when selecting and searching text is a requirement.
What scale should I use for print?
Begin with window.devicePixelRatio or 2, then validate memory use and legibility with your largest component. There is no universal best value.
Can I capture a private route?
A client-side export can capture content the signed-in browser can read. A remote API needs an authenticated, authorized way to reach that route; do not expose credentials in a public URL.
Frequently Asked Questions
Can SVG charts be exported sharply?
Usually, yes, when they are rendered inside the captured DOM; inspect filters, masks, and external resources because unsupported CSS or external assets can still differ.
Why does a one-page component become several PDF pages?
The PDF has fixed physical page dimensions. A component taller than the printable area must be sliced or paginated; forcing it onto one page shrinks it and makes text harder to read.
Is html2pdf.js a different renderer from html2canvas?
It is a wrapper workflow that uses html2canvas for DOM rendering and jsPDF for PDF creation, adding convenience options such as filename and page-break modes.
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.

