The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Short answer: CSS rules such as break-before: page, page-break-before: always, and break-inside: avoid target a browser’s print layout. React’s jsPDF.html() path is different: it renders through html2canvas and jsPDF’s context2d pagination logic. Therefore, a print-CSS rule is not a guaranteed page break in a PDF generated with .html(). For a boundary you can rely on, construct pages explicitly or render sections separately, measure their placement, and verify the result with the exact jsPDF, html2canvas, browser, device, and markup used by your application.
Why your CSS page break is ignored
The HTML module does not ask the browser to print your document. It paints the supplied element (or HTML string) with html2canvas and then places that rendered content into a jsPDF document. The jsPDF README identifies html2canvas as a dependency and notes that HTML strings also use DOMPurify. The module source currently routes context2d rendering through html2canvas and assigns pdf.context2d.autoPaging from the autoPaging option; when the option is omitted, the inspected source defaults it to true. See the HTML module source documentation.
This automatic pagination is based on the rendered canvas dimensions. It is not the browser print engine, and the inspected source does not implement a general pagebreak option that makes print CSS authoritative. The repository’s master branch changes over time, so confirm behavior against your installed release rather than treating the current source as a promise for every version.
That is why a rule can work in Chrome’s print preview and still have no effect in doc.html(). It may also appear to work for one document and fail when fonts, images, viewport width, mobile layout, or content height changes.
#1 Best Overall
First, identify the rendering path and versions
- Check the exact versions in your lockfile:
jspdfandhtml2canvas. A package manager command such asnpm ls jspdf html2canvasrecords what is actually installed. - Record the browser, operating system, device, viewport width, device-pixel ratio, and whether you pass a DOM element or an HTML string.
- Confirm that the element passed to
html()is the element containing the expected sections. A selector pointing at a wrapper, an empty ref, or a conditionally rendered React node can make a correct-looking CSS rule irrelevant. - Inspect the generated PDF, not only the on-screen DOM or browser print preview. Keep a minimal reproduction with the same fonts, images, CSS, and content lengths.
Reports in issue #3874 and issue #3766 are individual experiences. They demonstrate that mobile transitions and manually measured spacers can be problematic, but they do not establish a universal defect or one universal fix.
Use autoPaging for ordinary flow, not as a forced-break API
For a document that can flow naturally, let the HTML renderer paginate:
import { jsPDF } from 'jspdf';
const doc = new jsPDF({ unit: 'mm', format: 'a4' });
doc.html(document.getElementById('invoice'), {
autoPaging: true,
margin: [12, 12, 12, 12],
html2canvas: {
scale: 1,
useCORS: true
},
callback: (pdf) => pdf.save('invoice.pdf')
});
React does not change the option name; pass it in the options object. Automatic pagination is useful for variable-height text, but it does not mean a particular element will begin on a fresh page. Keep sections structurally simple, avoid relying on print-only declarations, and test long and short versions of the same content.
Reliable ways to force a section onto a new page
Approach 1: Render sections separately and add pages
The most controllable pattern is to render one section, then add a page and render the next section. You must choose a scale and placement that fit the page and verify the measured height for your versions.
import { jsPDF } from 'jspdf';
function renderHtml(pdf, element) {
return new Promise((resolve, reject) => {
pdf.html(element, {
autoPaging: false,
margin: [12, 12, 12, 12],
html2canvas: { scale: 1, useCORS: true },
callback: () => resolve(),
// html() reports failures through the browser console in some releases;
// keep your own timeout/error handling around the call in production.
});
});
}
async function exportReport() {
const pdf = new jsPDF({ unit: 'mm', format: 'a4' });
await renderHtml(pdf, document.getElementById('cover'));
pdf.addPage();
await renderHtml(pdf, document.getElementById('details'));
pdf.save('report.pdf');
}
This establishes a page boundary in the PDF itself. If a section can exceed one page, split it into smaller renderable blocks or allow that section’s own pagination. Do not assume that a CSS spacer has the same height after html2canvas scaling; the issue report in #3766 describes inaccurate manual measurements for one user’s spacer approach.
Approach 2: Build a page-aware layout
For repeatable forms, calculate the available page height in your chosen units, track the y-position of each block, and call addPage() before placing a block that will not fit. This requires a measured height from the actual rendered content. Web fonts loading late, external images, and responsive CSS can all change that height, so wait for assets and test the exact environment.
const pageHeight = pdf.internal.pageSize.getHeight();
const bottom = 12;
let y = 12;
function nextBlock(height) {
if (y + height > pageHeight - bottom) {
pdf.addPage();
y = 12;
}
const start = y;
y += height;
return start;
}
The snippet is only the placement decision; obtaining a trustworthy height is application-specific. Measure after fonts and images are ready, and compare the PDF output rather than trusting a pre-render DOM estimate.
Approach 3: Use CSS as a hint, then verify
You can keep semantic print styles such as break-before: page for browser printing, but treat them as non-authoritative for standalone jsPDF .html(). A class name like html2pdf__page-break is not a jsPDF feature.
Do not confuse jsPDF with html2pdf.js
html2pdf.js documents an explicit html2pdf__page-break class. Its README says the element is given a height calculated to fill the remainder of the PDF page, and for React markup it shows className="html2pdf__page-break". That behavior belongs to html2pdf.js’s pipeline. It is not evidence that standalone new jsPDF().html() honors that class or browser print directives.
| Question | Standalone jsPDF .html() |
html2pdf.js |
|---|---|---|
| Rendering path | jsPDF HTML module with html2canvas and context2d pagination | html2pdf.js workflow documented by its own README |
| Forced class documented? | Not established in the inspected source | html2pdf__page-break |
| Best fit | Explicit page construction or section rendering when boundaries matter | Projects willing to adopt its API and test its behavior |
| Migration cost | Keep current jsPDF integration | Change API, options, and regression tests |
Choose based on your requirements; html2pdf.js is not automatically better, and changing libraries does not remove the need to test fonts, assets, and responsive layouts.
React implementation checklist
- Use a ref that is non-null after the report is rendered; call export from an event after the relevant data is present.
- Wait for web fonts with
await document.fonts.readywhere supported, and ensure images are loaded. Use CORS-compatible image URLs when settinguseCORS: true. - Keep the capture viewport deterministic. A mobile breakpoint can change element heights and create different page transitions.
- Do not hide the report with
display:nonebefore capture; render it in a measurable container and hide it visually with an appropriate off-screen style if necessary. - Save a PDF from the same browser/device used in production and inspect every intended boundary.
Troubleshooting common failures
“page-break-before” has no effect
Cause: the rule targets browser print pagination, while .html() uses canvas rendering and automatic placement. Fix: use separate section renders with addPage(), or adopt the html2pdf.js-specific class only if you are actually using html2pdf.js.
The break works on desktop but not mobile
Cause: responsive dimensions, different font metrics, or a device-specific rendering path. Fix: capture the exact mobile reproduction, record versions and viewport, wait for assets, and make the boundary explicit instead of relying on a CSS hint.
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →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
A blank page appears
Cause: adding a page after a renderer already created one, or placing content beyond the available height. Fix: log page additions, use one owner for pagination, reset the y-position after addPage(), and check margins and scale.
Content is clipped or overlaps
Cause: an inaccurate height estimate or late-loading asset. Fix: wait for fonts/images, reduce the block to a measured section, and verify the rendered PDF. Avoid claiming a fixed pixel spacer is portable across browsers.
Images or fonts are missing
Cause: cross-origin restrictions, unavailable URLs, or fonts not loaded at capture time. Fix: serve assets with suitable CORS headers, set useCORS where appropriate, preload fonts, and include the asset conditions in your reproduction.
The PDF differs after upgrading
Cause: moving jsPDF/html2canvas behavior or changed browser rendering. Fix: pin and record versions, read the installed package’s documentation/source, and rerun visual regression checks before relying on a workaround.
Best Value
Or skip the browser setup
If your goal is simply a clean screenshot or PDF of a URL rather than a React component assembled in the browser, ScreenshotNeo provides a single API request. It accepts consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, with the result identified by X-Page-Verdict and X-Billed headers. Its MCP server exposes take_screenshot, get_page_info, and capture_pdf to Claude, Cursor, and other MCP clients. The Free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 shots.
cURL
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}`);
See the ScreenshotNeo API documentation for options such as full-page capture, element selectors, device presets, PDF paper settings, custom CSS/JavaScript, waits, request blocking, headers, cookies, geolocation, caching, signed links, asynchronous jobs, and bulk capture. Create a free ScreenshotNeo account to start with 1,000 screenshots per month and no card.
Frequently Asked Questions
Does setting autoPaging: false create a page break?
No. It changes automatic pagination behavior; it does not identify a CSS element that must start on a new page. Use explicit page construction or separate renders.
Can I use html2pdf__page-break in a jsPDF-only project?
Not as a documented jsPDF feature. That class is documented by html2pdf.js and requires its pipeline.
Recommended Free Tools
Should I switch libraries to solve every page-break issue?
No. First test explicit jsPDF page construction against your requirements. Switch only when html2pdf.js’s documented behavior and migration cost fit your project.
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.

