Get Started

Smart PDF Pagination

Use vue-pdf-export smart split controls, CSS page breaks, table headings and opt-in diagnostics in Vue.

Html2Pdf runs the shared DOM pagination planner when manualPagination is false and paginateElementsByHeight is supplied. That number is the usable CSS pixel height after margins and header/footer reservations, calculated for your chosen paper size and orientation. It is not a universal A4 constant. Direct useHtml2Pdf() generation does not run the component planner.

Version 1.3.0 also supports a simple Options API or Composition API PDF with no pagination props: the selected renderer handles basic flow. Set a positive finite height to use the component's smart planner for keep-together rules and table rows. In the playground, manual pagination is the demo default, and the optional media/chart section has an authored break before it. A large section may continue onto another physical page. Oversized rows and unusual CSS still need PDF inspection.

<script setup lang="ts">
import { Html2Pdf } from 'vue-pdf-export'
import 'vue-pdf-export/style.css'

// Example budget for this application's measured paper geometry and insets.
const usablePageHeightPx = 960
</script>

<template>
  <Html2Pdf :manual-pagination="false" :paginate-elements-by-height="usablePageHeightPx">
    <template #pdf-content>
      <section data-pdf-split="avoid"><h2>Summary</h2><p>Keep this block together if it fits.</p></section>
      <section data-pdf-split="container">
        <header data-pdf-split-header>Repeated section heading</header>
        <article>First child</article>
        <article>Second child</article>
      </section>
    </template>
  </Html2Pdf>
</template>

Recalculate the budget when format, orientation, explicit margins, content width or layer heights change. The paper format guide explains geometry.

Split controls

MarkupEffect
data-pdf-split="avoid"Move a fitting block together; oversized blocks can fall back to child boundaries.
data-pdf-split="container"Split long and nested sections around children, accounting for computed padding and flex/grid gaps.
data-pdf-split-headerMark a child heading for repetition when its container continues.
.pdf-keep-together, .pdf-no-break, imgExisting default avoidance rules.

In supported selectable-text layouts, continuation fragments can retain a frame with page-edge spacing and rounded borders. Renderer CSS support varies. Indivisible oversized media, rowspans and complex nested layouts may still split or scale; inspect representative exports.

Explicit page breaks

<section style="break-before: page">Start on a new page.</section>
<section style="break-after: page">The next block starts on a new page.</section>
<div class="html2pdf__page-break"></div>

Legacy page-break-before and page-break-after also work. Do not put an explicit CSS break on the .html2pdf__page-break marker: that can produce two breaks or blank pages. manual-pagination="true" is useful when you author your own markers. Elements without the new attributes retain existing behavior.

Long tables

Use one semantic heading and ordinary rows. The planner can split across multiple <tbody> groups, honor explicit row breaks, move an orphan heading with its first row and repeat <thead> on continuation pages. Do not manually copy the heading.

<template>
  <table>
    <thead><tr><th scope="col">Item</th><th scope="col">Amount</th></tr></thead>
    <tbody>
      <tr v-for="item in 40" :key="item">
        <td>Item {{ item }}</td><td>${{ item * 10 }}</td>
      </tr>
    </tbody>
  </table>
</template>

Selectable-text rendering carries the computed heading background into repeated rows. Canvas continuation fragments suppress a second native heading repetition. Check complex rowspan, unsupported CSS and oversized rows in the output.

Diagnose page boundaries

<script setup lang="ts">
import { Html2Pdf } from 'vue-pdf-export'
import type { PdfPaginationDiagnostic } from 'vue-pdf-export'
import 'vue-pdf-export/style.css'

function onBreak(decision: PdfPaginationDiagnostic) {
  console.info(decision.type, decision.page, decision.reason)
}
</script>

<template>
  <Html2Pdf :manual-pagination="false" :paginate-elements-by-height="960"
    :pagination-debug="true" @pagination-break="onBreak"
    @pagination-warning="onBreak" @pagination-complete="(all) => console.info(all)">
    <template #pdf-content><article>Measured report content</article></template>
  </Html2Pdf>
</template>

Possible diagnostic types are automatic, manual-break, break-before, break-after, avoid-moved, container-split, table-split, and oversized. The opt-in overlay and events show planner decisions on the live DOM. The overlay is not a PDF layer or proof of final viewer alignment. Pagination has a finite fallback and cancellation checks; it cannot guarantee that arbitrary text, SVG or CSS never tears.

Copyright © 2026