Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

html2pdf.js does not document a reliable option that repeats a table’s <thead> on every PDF page. Its page-break settings control where content is split or kept together, while its rendering path turns the HTML into an image before placing that image in the PDF. Browser print behavior therefore cannot be assumed to survive pagination.

Keep your table semantically correct and test the real PDF. If repeated headings are a hard requirement, use a table-aware renderer such as jsPDF-AutoTable, which documents showHead: 'everyPage', or xhtml2pdf, which documents repeating <thead> rows. The sections below show the safest html2pdf.js setup, the experiments worth trying, and how to decide whether to change tools.

Why html2pdf.js does not promise repeated headers

The important distinction is between a browser’s print layout engine and html2pdf.js pagination. The html2pdf.js documentation describes an output path in which the library renders content into an image and then places that image into a PDF. A semantic table header is still valuable HTML, but the library does not document automatic repetition of that header after the image has been divided across PDF pages.

Its documented pagebreak option handles break placement and avoidance. The supported modes are avoid-all, css, and legacy; the before, after, and avoid selectors determine where breaks are inserted or avoided. None of those settings is a repeated-table-header switch.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

What this means in practice

  • A <thead> is the correct semantic structure, but it is not a documented guarantee that html2pdf.js will draw the header again.
  • thead { display: table-header-group; } is worth testing, not treating as a supported fix.
  • The only reliable verdict is the PDF produced by the exact browser, operating system, html2pdf.js version, page format, margins, scale, and page-break settings you ship.

Start with a correct, reproducible table

Before changing CSS or pagination, reduce the problem to a table that unquestionably crosses a page boundary. Keep all headings in <thead> and all records in <tbody>. Do not place header rows in the body and expect the converter to infer their role.

<section id="report">
  <h1>Monthly orders</h1>
  <table class="orders">
    <thead>
      <tr>
        <th scope="col">Item</th>
        <th scope="col">Description</th>
        <th scope="col">Total</th>
      </tr>
    </thead>
    <tbody id="order-rows"></tbody>
  </table>
</section>

<script>
  const rows = document.querySelector('#order-rows');
  for (let i = 1; i <= 80; i += 1) {
    rows.insertAdjacentHTML('beforeend', `
      <tr>
        <td>Order ${i}</td>
        <td>A deliberately long description for a controlled page-break test.</td>
        <td>$${(i * 12.5).toFixed(2)}</td>
      </tr>`);
  }
</script>

Generate or load the rows before calling html2pdf.js. A table that is still changing while capture starts can produce a misleading result, including a header that appears detached from the first data row.

Use html2pdf.js page-break controls correctly

The following is a controlled starting point. It asks html2pdf.js to consider CSS and legacy break rules and sets an explicit PDF format so that later comparisons are meaningful.

html2pdf().set({
  pagebreak: { mode: ['css', 'legacy'] },
  jsPDF: { format: 'letter', orientation: 'portrait' }
}).from(document.querySelector('#report')).save();

What each setting can and cannot do

  • mode: 'css': uses CSS break rules. In the documented behavior, always, left, and right are recognized for breaks before or after an element, and avoid is recognized for breaks inside.
  • mode: 'legacy': preserves the library’s legacy break handling. Combining it with CSS mode is useful when an existing report already contains legacy break markers.
  • mode: 'avoid-all': attempts to keep elements together. It can reduce row splitting, but it is not a header-repeat feature and may create large gaps or unexpected page placement.
  • before and after: selectors at which a new page may be inserted.
  • avoid: selectors that should not be split internally where the renderer can honor that request.

Use these controls to keep a heading with the first row or to avoid breaking a small card. Do not use them as evidence that a <thead> will be painted on every page.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #2
Sale
HTML and CSS: Design and Build Websites
  • HTML CSS Design and Build Web Sites
  • Comes with secure packaging
  • It can be a gift option

Test the common CSS workaround, but verify the PDF

Many implementations try the browser-print rule below:

.orders thead {
  display: table-header-group;
}

.orders tr {
  break-inside: avoid;
  page-break-inside: avoid;
}

This is valid as an experiment in the exact environment you deploy. It can help a renderer that honors table pagination, but the html2pdf.js documentation does not promise that it will repeat a header after canvas capture and image pagination. Treat a successful result as version- and layout-specific until you have regression-tested it.

Check these failure patterns

  • Header missing on later pages: this is the expected limitation when the image is split without table-aware pagination.
  • Header separated from its first row: a break rule, margin, or a long row may have moved the row to the next page. Inspect the generated PDF rather than only the browser preview.
  • Rows clipped at a boundary: test without avoid-all, reduce the row’s internal height, and check whether a long cell contains unbreakable text.
  • Unexpected whitespace: avoid-all, large margins, and a scale that no longer fits the chosen page can leave unused space.
  • CSS appears ignored: html2pdf.js clones and resizes content during rendering. Confirm that the selector still matches the cloned node and that the style is loaded before capture begins.

Make a minimal diagnostic case

When the output is wrong, remove application code until only one table crosses a page. Keep the table width, font, and cell content representative of production; otherwise you may diagnose a layout that cannot reproduce the real failure.

  1. Render a single report element containing one <table>, one <thead>, and enough <tbody> rows to create at least two pages.
  2. Record the browser and operating-system versions and the installed html2pdf.js version.
  3. Record every capture option, especially PDF format, orientation, margins, scale, and page-break mode.
  4. Capture the resulting PDF and a screenshot of the source page at the same viewport size.
  5. Change one variable at a time: first page-break mode, then margins, then scale, then CSS.

This matters because html2canvas rendering, cloned-node styles, root-element resizing, page dimensions, and long cells can each change the final pagination. A report that works in a browser preview can still fail after the clone and rasterization steps.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

When repeated headings are a firm requirement

If readers must see column labels at the top of every continued page, choose a renderer whose documentation exposes that behavior instead of relying on an undocumented side effect.

Approach Repeated-header behavior in the cited documentation What to compare before migrating
html2pdf.js No repeated-table-header option documented HTML styling fidelity, current output quality, page-break controls, and sensitivity to canvas rendering and reflow
jsPDF-AutoTable showHead includes everyPage, firstPage, and never Whether your application can build the table through the plugin, plus its data-driven layout and styling model
xhtml2pdf Documents repeating <thead> rows when a table continues onto another page Server-side or Python fit, layout constraints, styling needs, and long-cell handling

jsPDF-AutoTable

With jsPDF-AutoTable, the repeated-heading decision is explicit: configure showHead as 'everyPage' when every page needs the column labels. This is a data-table layout model, so compare the amount of HTML and CSS fidelity you need against the work required to construct the table through the plugin.

xhtml2pdf

xhtml2pdf documents that table rows in <thead> repeat at the top of every page that the table runs over. It is a different, server-side/Python-oriented rendering path, so evaluate deployment, supported CSS, long-cell behavior, and whether moving PDF generation out of the browser is acceptable.

Do not migrate solely because a demo looks right

Run your real table through the candidate renderer: long descriptions, wrapped numbers, hidden columns, custom fonts, totals, and the page sizes your users select. A repeated heading is useful only if the rest of the report remains readable and stable.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #4
Sale
Web Design with HTML, CSS, JavaScript and jQuery Set
  • Brand: Wiley
  • Set of 2 Volumes
  • A handy two-book set that uniquely combines related technologies Highly visual format and accessible language makes these books highly effective learning tools Perfect for beginning web designers and front-end developers

Reliability and performance considerations

Rasterization changes the trade-off

Because html2pdf.js renders content into an image before placing it in the PDF, the output is sensitive to viewport dimensions, scale, margins, and the size of the captured DOM. Larger reports and higher scales require more rendering work and can expose memory or timeout problems in the browser. Keep the capture region limited to the report, avoid unnecessary off-screen content, and test the largest table you expect users to export.

Long rows need special attention

A row containing a long unbreakable URL, code token, or oversized image can force a bad break even when ordinary rows look fine. Permit sensible wrapping, constrain media dimensions, and test rows that are substantially taller than the header. If preserving an entire row creates unacceptable blank space, prefer a renderer with table-aware layout rather than increasingly aggressive avoid rules.

Keep output settings stable

Changing from letter to another format, switching portrait to landscape, altering margins, or changing scale changes the available width and height. Re-run the PDF checks after each such change. A CSS workaround that appears to repeat a header at one page width is not a general guarantee.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshooting checklist

Only the first page has the header

Confirm that the table is semantic, then test the table-header-group rule in the exact browser and library version. If the header still appears once, stop tuning break modes: html2pdf.js has no documented repeated-header option. Move to jsPDF-AutoTable or xhtml2pdf when the requirement is non-negotiable.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The first data row moves to a new page

Inspect margins, heading height, and any before, after, or avoid selectors. Remove avoid-all temporarily and test a short first row. This identifies whether a keep-together rule, rather than header handling, is responsible.

A row is cut or text disappears

Test the row without long unbroken text or large images. Check the cloned report element’s computed styles, then try a lower scale or a larger page format. Do not assume that browser layout and the rasterized clone have identical dimensions.

Results differ between machines

Capture with the same browser family and version, operating-system fonts, viewport, page format, margins, scale, and html2pdf.js version. Include those details in a minimal bug report. Also include the smallest table that crosses a page boundary and the generated PDF or screenshot.

Or skip the browser setup

If your actual requirement is a clean image or PDF of a report page—not control over html2pdf.js’s internal table pagination—ScreenshotNeo can capture the URL through one HTTP request. It is a separate capture path, so it does not make html2pdf.js repeat a <thead>; it gives you a way to obtain the rendered page without maintaining browser automation.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

See the ScreenshotNeo API documentation for request options. A basic capture is:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com/report -o report.webp

Equivalent calls:

import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://example.com/report"},
    timeout=90,
)
r.raise_for_status()
open("report.webp", "wb").write(r.content)
const q = new URLSearchParams({
  access_key: 'YOUR_API_KEY',
  url: 'https://example.com/report'
});
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot failed: ${res.status}`);
const data = Buffer.from(await res.arrayBuffer());
await Bun.write('report.webp', data);

ScreenshotNeo accepts the cookie or consent banner like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each cleanup step can be disabled. Bot checks and CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the result with 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, and every feature is available on every plan. Sign up for the free ScreenshotNeo plan if that capture workflow fits your report.

Bottom line

Use semantic table markup and html2pdf.js page-break controls for sensible pagination, but do not promise that <thead> will repeat. Test the actual PDF, and switch to jsPDF-AutoTable or xhtml2pdf when repeated headings are a strict output requirement.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Quick Recap

SaleBestseller No. 2
HTML and CSS: Design and Build Websites
HTML and CSS: Design and Build Websites
HTML CSS Design and Build Web Sites; Comes with secure packaging; It can be a gift option
$14.94
SaleBestseller No. 4
Web Design with HTML, CSS, JavaScript and jQuery Set
Web Design with HTML, CSS, JavaScript and jQuery Set
Brand: Wiley; Set of 2 Volumes
$35.05

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.