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 minutePC 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 & 11Render every target <div> into its own canvas, add the first canvas to a jsPDF document, call addPage() before each later canvas, and save only after the loop finishes. Sequential await calls preserve document order and let you size every image to the PDF page without distortion.
Complete browser implementation
Install the two browser libraries in your project:
npm install @html2canvas/html2canvas jspdf
Give each exportable section a common class:
<section class="pdf-page">
<h1>Invoice 1001</h1>
<p>Customer and line-item details…</p>
</section>
<section class="pdf-page">
<h1>Invoice 1002</h1>
<p>Customer and line-item details…</p>
</section>
<button id="export-pdf" type="button">Export PDF</button>
Then import the packages and export the sections in document order:
import html2canvas from '@html2canvas/html2canvas';
import { jsPDF } from 'jspdf';
async function exportDivs() {
const nodes = [...document.querySelectorAll('.pdf-page')];
if (nodes.length === 0) {
throw new Error('No elements matched .pdf-page');
}
const pdf = new jsPDF({
orientation: 'portrait',
unit: 'mm',
format: 'a4'
});
for (let i = 0; i < nodes.length; i += 1) {
const node = nodes[i];
const canvas = await html2canvas(node, {
scale: Math.min(window.devicePixelRatio || 1, 2),
useCORS: true,
windowWidth: node.scrollWidth,
windowHeight: node.scrollHeight
});
if (i > 0) {
pdf.addPage();
}
const image = canvas.toDataURL('image/png');
const pageWidth = pdf.internal.pageSize.getWidth();
const pageHeight = pdf.internal.pageSize.getHeight();
const ratio = Math.min(pageWidth / canvas.width, pageHeight / canvas.height);
const width = canvas.width * ratio;
const height = canvas.height * ratio;
const x = (pageWidth - width) / 2;
const y = (pageHeight - height) / 2;
pdf.addImage(image, 'PNG', x, y, width, height);
}
pdf.save('div-pages.pdf');
}
document.querySelector('#export-pdf').addEventListener('click', () => {
exportDivs().catch((error) => {
console.error(error);
alert('The PDF could not be created. Check the console for details.');
});
});
The first canvas uses the page created by the jsPDF constructor. Every later iteration adds exactly one page first, preventing a leading blank page and ensuring a one-div-to-one-page mapping.
How the sizing calculation works
html2canvas returns a canvas whose dimensions are pixels. jsPDF reports its page dimensions in the unit selected in the constructor, millimetres in this example. The ratio is the smaller of the width ratio and height ratio, so the complete canvas fits inside A4 while retaining its aspect ratio. Centering is calculated from the unused width and height.
#1 Best Overall
- Create and edit PDFs. Collaborate with ease. E-sign documents and collect signatures. Get everything done in one app, wherever you go.
- Edit text and images without jumping to another app.
- E-sign documents or request e-signatures on any device. Recipients don’t need to log in to e-sign.
- Convert PDFs to editable Microsoft Word, Excel, or PowerPoint documents.
- Share PDFs for collaboration. Commenting features make it easy for reviewers to comment, mark up, and annotate.
A4 portrait is 210 × 297 mm. For landscape output, change orientation to 'landscape'. You can also pass a custom format or dimensions supported by jsPDF. Pixel units require jsPDF's px_scaling hotfix; using millimetres avoids that conversion in most print workflows.
Margins and deliberate whitespace
To create a 10 mm margin, subtract 20 from both page dimensions before calculating the ratio, then add the margin to x and y:
const margin = 10;
const usableWidth = pageWidth - margin * 2;
const usableHeight = pageHeight - margin * 2;
const ratio = Math.min(usableWidth / canvas.width, usableHeight / canvas.height);
const width = canvas.width * ratio;
const height = canvas.height * ratio;
const x = margin + (usableWidth - width) / 2;
const y = margin + (usableHeight - height) / 2;
PNG versus JPEG
PNG preserves sharp text, borders and transparency but can produce larger files. JPEG can reduce size for photographic content at the cost of compression artifacts and no transparency:
const image = canvas.toDataURL('image/jpeg', 0.ಚ್ಚ9);
pdf.addImage(image, 'JPEG', x, y, width, height);
Replace the malformed-looking decimal above with a normal JavaScript value such as 0.9; the complete line is:
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Rank #2
- Create and edit PDFs. Collaborate with ease. E-sign documents and collect signatures. Get everything done in one app, wherever you go.
- Edit text and images without jumping to another app.
- E-sign documents or request e-signatures on any device. Recipients don’t need to log in to e-sign.
- Convert PDFs to editable Microsoft Word, Excel, or PowerPoint documents.
- Share PDFs for collaboration. Commenting features make it easy for reviewers to comment, mark up, and annotate.
const image = canvas.toDataURL('image/jpeg', 0.9);
Control resolution with html2canvas options
scale: increases output pixels for sharper text.window.devicePixelRatiois a useful starting point; cap it when memory is a concern.useCORS: true: asks image requests to use CORS. The image server must send a suitableAccess-Control-Allow-Originheader.windowWidthandwindowHeight: matching the element'sscrollWidthandscrollHeighthelps avoid clipped or empty captures.data-html2canvas-ignore: add this attribute to controls, buttons or other content that should not appear in the canvas.x,y,widthandheight: capture a specific viewport region when a whole element is not required.
html2canvas approximates browser rendering; CSS support is not complete, so unusual filters, effects and newer layout features may differ from the live page. It runs in modern evergreen browsers and returns a Promise resolving to a canvas; it is not a Node.js renderer.
Prevent missing content before rendering
Wait for data, fonts and images that your page loads asynchronously. A simple application-level wait is often enough:
await document.fonts.ready;
await Promise.all(
[...document.images]
.filter((image) => !image.complete)
.map((image) => new Promise((resolve) => {
image.addEventListener('load', resolve, { once: true });
image.addEventListener('error', resolve, { once: true });
}))
);
For a component that expands after data arrives, call exportDivs() only after the expansion has completed. Rendering while a layout is still changing can produce inconsistent page heights.
Oversized divs and browser canvas limits
The loop assigns one canvas to one PDF page; it does not split a very tall div across multiple pages. If the div exceeds the page, the aspect-ratio calculation shrinks it to fit, potentially making text unreadable. Choose one of these approaches:
Rank #3
- Perfect Adobe Acrobat Pro alternative – lifetime license for Windows 10 and 11.
- EDIT text, images, pages, hyperlinks, designs in PDF documents. ORGANIZE PDFs.
- READ and Comment on PDFs – Intuitive reading modes & document commenting and mark up tools!
- CREATE, COMBINE, SCAN and COMPRESS PDFs.
- FILL forms & Digitally Sign PDFs. Work with Digital certificates
- Design each exportable div to fit a page.
- Accept the smaller rendering by lowering content density or using a larger PDF format.
- Write a slicing routine that renders the element and adds cropped portions to multiple PDF pages.
- Use a document-oriented PDF renderer when selectable text and pagination matter more than pixel fidelity.
Canvas maximum dimensions vary by browser, operating system and available memory. Test realistic, image-heavy content rather than relying only on a short development fixture. Lowering scale, capturing smaller sections and compressing photographs reduce memory pressure.
Cross-origin images: why they disappear
A page can display an image normally while html2canvas cannot read it into a canvas. The browser's same-origin policy may taint the canvas when the image comes from another origin without permission. useCORS: true works only when that server supplies the appropriate CORS response header. Otherwise, serve the asset from your own origin or use a server-side proxy that you control. html2canvas cannot bypass browser content-policy restrictions.
After a canvas is tainted, calls such as toDataURL() can fail. Treat that as an asset configuration problem, not a jsPDF page-order problem.
Why the first page is blank
- Adding a page before the first image: the constructor already created page one. Use
if (i > 0) pdf.addPage(). - Saving before asynchronous rendering finishes: keep
pdf.save()after the loop and await everyhtml2canvascall. - An empty selector result: verify the class name and run the export after the DOM has mounted.
- A zero-sized or hidden element: render a visible element with measurable dimensions, or temporarily apply export-specific styles.
Sequential rendering, errors and progress
A sequential for...of or indexed loop is intentional. Running many captures simultaneously can consume substantial memory and make ordering harder to guarantee. Add progress reporting and per-div error handling when a batch is long:
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Rank #4
- EDIT text, images & designs in PDF documents. ORGANIZE PDFs. Convert PDFs to Word, Excel & ePub.
- READ and Comment PDFs – Intuitive reading modes & document commenting and mark up.
- CREATE, COMBINE, SCAN and COMPRESS PDFs
- FILL forms & Digitally Sign PDFs. PROTECT and Encrypt PDFs
- LIFETIME License for 1 Windows PC or Laptop. 5GB MobiDrive Cloud Storage Included.
for (let i = 0; i < nodes.length; i += 1) {
try {
// render and add nodes[i]
console.log(`Rendered ${i + 1} of ${nodes.length}`);
} catch (error) {
console.error(`Could not render div ${i + 1}`, error);
throw error; // stop rather than silently creating an incomplete PDF
}
}
If you prefer a usable partial document, record failures and continue, but clearly tell the user which pages were omitted. Do not call save until your chosen failure policy has completed.
Alternative: html2pdf.js
html2pdf.js wraps the same general pipeline with .from() -> .toContainer() -> .toCanvas() -> .toImg() -> .toPdf() -> .save() and accepts html2canvas and jsPDF options. It is convenient when built-in page-break controls are sufficient. Its output is image-based: text is not selectable or searchable, files can be large, and the HTML5 canvas size limitation still applies. For a separate page per div, the direct loop above gives clearer control over page order, margins, per-element options and failures.
Can html2canvas run on a server?
No. html2canvas runs entirely in a user's browser and is not suitable for Node.js. For server-side generation, use a real browser automation stack such as Puppeteer or Playwright, load the page in that browser, and then print or capture it. This adds browser installation, authentication, fonts, network access and resource-lifecycle concerns that do not exist in a purely client-side export.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Or skip the browser setup
If you need a hosted screenshot or PDF capture of a URL rather than a client-side loop over individual divs, ScreenshotNeo provides a website screenshot API and MCP server. A single GET request returns a PNG, JPEG, WebP or PDF. It accepts consent banners before capture and removes more than 60 known consent platforms, newsletter popups and chat widgets; those steps 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.
Recommended Free Tools
For a screenshot request, see the ScreenshotNeo API documentation:
Best Value
- Full-featured PDF Editor: Edit text in the document
- Fully convert PDF to Word and Excel and continue editing
- NEW: Further development of existing functions
- NEW: Even faster and more user-friendly
- NEW: Over 75 small improvements in all areas
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)
r.raise_for_status()
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}`);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const buffer = Buffer.from(await res.arrayBuffer());
require('node:fs').writeFileSync('shot.webp', buffer);
ScreenshotNeo also offers an MCP server with take_screenshot, get_page_info and capture_pdf for Claude, Cursor and other MCP clients. It supports full-page captures, CSS-selector elements, device and viewport settings, custom CSS or JavaScript, waits, request blocking, cookies, headers, geolocation, signed links, asynchronous webhooks and bulk capture. The Free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.
Practical checklist
- Confirm the selector returns the divs in the intended order.
- Wait for data, fonts and images before starting.
- Use a deliberate
scaleand test memory use on long pages. - Set
useCORSand configure image servers or a proxy for cross-origin assets. - Match window dimensions to scroll dimensions for tall content.
- Add pages only when
i > 0. - Fit with an aspect-ratio calculation and keep margins explicit.
- Save only after every asynchronous render and error decision is complete.
Frequently Asked Questions
Will the PDF contain selectable text?
No. This workflow places each html2canvas bitmap into jsPDF, so the result is image-based rather than a text-layout PDF.
Can one div become several PDF pages automatically?
No. The one-div-per-page loop scales each canvas to one page. Tall content must be redesigned, shrunk, or sliced with a separate pagination routine.
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 →Why does an image work in the page but fail in the export?
The image may be cross-origin without a permitting CORS header. Enable useCORS and configure the image server, or proxy the asset from a permitted origin.
What should I use for automated server exports?
Use Puppeteer or Playwright for a real browser. html2canvas itself is a client-side library and does not run as a Node.js renderer.
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.

