Structure
Core layout components
Document
<Document />The root container for your PDF. Sets document metadata and loads fonts.
import { Document, Page } from "@pdfn/react";
export default function Invoice() {
return (
<Document
title="Invoice #001"
fonts={[
// Google Fonts (loaded from CDN)
"Inter",
{ family: "Roboto Mono", weights: [400, 700] },
// Local fonts (embedded as base64)
{ family: "CustomFont", src: "./fonts/custom.woff2", weight: 400 },
]}
>
<Page size="A4" margin="1in">
{/* Your content */}
</Page>
</Document>
);
}Props
| Name | Type | Description |
|---|---|---|
title | string | PDF document title (shown in browser tab) |
author | string | PDF author metadata |
subject | string | PDF subject metadata |
keywords | string[] | PDF keywords metadata |
language | string | Document language(default: "en") |
fonts | (string | FontConfig)[] | Google Fonts (by name) or local fonts (with src path)(default: []) |
children | ReactNode | Page components |
Page
<Page />Defines a page with size, margins, and optional headers/footers. Content automatically flows across multiple pages.
<Page
size="A4"
orientation="portrait"
margin={{ top: "1in", right: "0.75in", bottom: "1in", left: "0.75in" }}
background="#ffffff"
header={<Header />}
footer={<Footer />}
watermark={{ text: "DRAFT", opacity: 0.1, rotation: -35 }}
>
{/* Content flows automatically */}
</Page>Props
| Name | Type | Description |
|---|---|---|
size | "A4" | "A3" | "A5" | "Letter" | "Legal" | "Tabloid" | "B4" | "B5" | [w, h] | Page size preset or custom dimensions(default: "A4") |
orientation | "portrait" | "landscape" | Page orientation(default: "portrait") |
margin | string | { top, right, bottom, left } | Page margins(default: "1in") |
background | string | Background color(default: "#ffffff") |
header | ReactNode | Content repeated at top of each page |
footer | ReactNode | Content repeated at bottom of each page |
watermark | string | { text, opacity?, rotation? } | Watermark text overlay on every page |
children | ReactNode | Page content |
Pagination
Page numbering and breaks
PageNumber
<PageNumber />Displays the current page number using CSS counters. Typically used in headers or footers.
<Page
footer={
<div className="text-center text-sm text-gray-500">
Page <PageNumber />
</div>
}
>
{/* Content */}
</Page>Props
| Name | Type | Description |
|---|---|---|
className | string | Additional CSS classes |
TotalPages
<TotalPages />Displays the total page count using CSS counters. Combine with PageNumber for "Page 1 of 5" style footers.
<Page
footer={
<div className="text-center text-sm text-gray-500">
Page <PageNumber /> of <TotalPages />
</div>
}
>
{/* Content */}
</Page>Props
| Name | Type | Description |
|---|---|---|
className | string | Additional CSS classes |
PageBreak
<PageBreak />Forces a page break. Content after this element starts on a new page.
<div>
<section>
<h2>Chapter 1</h2>
<p>First chapter content...</p>
</section>
<PageBreak />
<section>
<h2>Chapter 2</h2>
<p>Second chapter content...</p>
</section>
</div>Content Control
Control how content flows
AvoidBreak
<AvoidBreak />Keeps wrapped content together on the same page. Prevents awkward breaks in the middle of a section.
{sections.map((section) => (
<AvoidBreak key={section.id}>
<h2 className="text-xl font-bold">{section.title}</h2>
<p className="mt-2">{section.content}</p>
</AvoidBreak>
))}Props
| Name | Type | Description |
|---|---|---|
children | ReactNode | Content to keep together |
className | string | Additional CSS classes |
Thead
<Thead />Enhanced <thead> - add repeat prop to repeat headers on each page when a table spans multiple pages.
<table className="w-full">
<Thead repeat>
<tr className="border-b">
<th className="text-left py-2">Item</th>
<th className="text-right py-2">Qty</th>
<th className="text-right py-2">Price</th>
</tr>
</Thead>
<tbody>
{items.map((item) => (
<Tr key={item.id} keep>
<td className="py-2">{item.name}</td>
<td className="text-right py-2">{item.quantity}</td>
<td className="text-right py-2">${item.price}</td>
</Tr>
))}
</tbody>
</table>Props
| Name | Type | Description |
|---|---|---|
children | ReactNode | Table row(s) for header |
repeat | boolean | Repeat header on each page |
className | string | Additional CSS classes |
Tr
<Tr />Enhanced <tr> - add keep prop to prevent row from splitting across pages.
<tbody>
{items.map((item) => (
<Tr key={item.id} keep>
<td>{item.name}</td>
<td>{item.price}</td>
</Tr>
))}
</tbody>Props
| Name | Type | Description |
|---|---|---|
children | ReactNode | Table cells |
keep | boolean | Prevent row from splitting across pages |
className | string | Additional CSS classes |