> ## Documentation Index
> Fetch the complete documentation index at: https://pdfn.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Components

> Reference for Document, Page, PageNumber, TotalPages, PageBreak, NoBreak, and table helper components. Includes props and usage examples.

This page explains how to build PDF templates from scratch. To scaffold a template, run `npx pdfn add invoice` (see [Quickstart](/quickstart)).

## Template structure

Every template is a React component that exports a `Document` containing one or more `Page` components:

```tsx pdfn-templates/my-template.tsx theme={null}
import { Document, Page } from '@pdfn/react';

interface MyTemplateProps {
  title: string;
  content: string;
}

function MyTemplate({ title, content }: MyTemplateProps) {
  return (
    <Document title={title}>
      <Page size="A4" margin="1in">
        <h1>{title}</h1>
        <p>{content}</p>
      </Page>
    </Document>
  );
}

// PreviewProps provides sample data for dev server preview
MyTemplate.PreviewProps = {
  title: 'My Document',
  content: 'Hello, world!',
} satisfies MyTemplateProps;

export default MyTemplate;
```

Save this file in `pdfn-templates/` and it will appear in the dev server preview (`npx pdfn dev`).

***

## Document

The root wrapper for every PDF template. Sets metadata and loads custom fonts.

```tsx theme={null}
import { Document, Page } from '@pdfn/react';

export default function MyPdf() {
  return (
    <Document
      title="Invoice #001"
      author="Acme Corp"
      css={`.custom { color: red; }`}
      fonts={["Inter"]}
    >
      <Page size="A4">
        <h1>Content</h1>
      </Page>
    </Document>
  );
}
```

### Document props

| Prop       | Type                       | Description                                      |
| ---------- | -------------------------- | ------------------------------------------------ |
| `title`    | `string`                   | PDF title (shows in browser tab and PDF readers) |
| `author`   | `string`                   | PDF author metadata                              |
| `subject`  | `string`                   | PDF subject metadata                             |
| `keywords` | `string[]`                 | PDF keywords for search                          |
| `creator`  | `string`                   | Application name that created the PDF            |
| `language` | `string`                   | Document language (default: `"en"`)              |
| `css`      | `string`                   | Custom CSS injected into the document            |
| `fonts`    | `(string \| FontConfig)[]` | Custom fonts to load                             |
| `children` | `ReactNode`                | Page components (required)                       |

### Fonts

Pass font names for Google Fonts, or font config objects for local files:

```tsx theme={null}
// Google Fonts
<Document fonts={["Inter", "Roboto Mono"]}>

// Local fonts
<Document fonts={[
  { family: "CustomFont", src: "./fonts/custom.woff2", weight: 400 },
]}>
```

See [Styling — Fonts](/styling#fonts) for configuration options and edge runtime considerations.

***

## Page

Defines a page with size, margins, headers, footers, and content.

```tsx theme={null}
import { Document, Page, PageNumber } from '@pdfn/react';

<Document title="Invoice">
  <Page
    size="A4"
    orientation="portrait"
    margin="1in"
    background="#ffffff"
    header={<div>Acme Corp</div>}
    footer={<PageNumber />}
    watermark="DRAFT"
  >
    <h1>Page content here</h1>
  </Page>
</Document>
```

### Page props

| Prop          | Type                          | Default      | Description                             |
| ------------- | ----------------------------- | ------------ | --------------------------------------- |
| `size`        | `PageSize`                    | `'A4'`       | Page dimensions                         |
| `orientation` | `'portrait'` \| `'landscape'` | `'portrait'` | Page orientation                        |
| `margin`      | `string` \| `object`          | `'1in'`      | Page margins                            |
| `background`  | `string`                      | `'#ffffff'`  | Background color                        |
| `header`      | `ReactNode`                   | —            | Content repeated at top of each page    |
| `footer`      | `ReactNode`                   | —            | Content repeated at bottom of each page |
| `watermark`   | `string` \| `object`          | —            | Watermark text or config                |
| `children`    | `ReactNode`                   | —            | Page content (required)                 |

### Page sizes

```typescript theme={null}
type PageSize =
  | 'A3' | 'A4' | 'A5'
  | 'Letter' | 'Legal' | 'Tabloid'
  | 'B4' | 'B5'
  | [string, string]; // Custom: [width, height] e.g. ['8.5in', '11in']
```

### Margin formats

```tsx theme={null}
// Single value (all sides)
<Page margin="1in">

// Two values (vertical, horizontal)
<Page margin="1in 0.5in">

// Object (each side)
<Page margin={{ top: '1in', right: '0.5in', bottom: '1in', left: '0.5in' }}>
```

### Watermark formats

```tsx theme={null}
// Simple string
<Page watermark="DRAFT">

// With options
<Page watermark={{ text: 'CONFIDENTIAL', opacity: 0.1, rotation: -35 }}>
```

***

## PageNumber

Displays the current page number. Use in headers or footers.

```tsx theme={null}
import { Document, Page, PageNumber } from '@pdfn/react';

<Document title="Report">
  <Page
    size="A4"
    footer={
      <div style={{ textAlign: 'center' }}>
        Page <PageNumber />
      </div>
    }
  >
    <h1>Report content</h1>
  </Page>
</Document>
```

Accepts a `className` prop for styling.

***

## TotalPages

Displays the total page count. Combine with `PageNumber` for "Page 1 of 5" style footers.

```tsx theme={null}
import { Document, Page, PageNumber, TotalPages } from '@pdfn/react';

<Document title="Report">
  <Page
    size="A4"
    footer={
      <div style={{ textAlign: 'center' }}>
        Page <PageNumber /> of <TotalPages />
      </div>
    }
  >
    <h1>Report content</h1>
  </Page>
</Document>
```

Accepts a `className` prop for styling.

***

## PageBreak

Forces content after it to start on a new page.

```tsx theme={null}
import { Document, Page, PageBreak } from '@pdfn/react';

<Document title="Book">
  <Page size="A4">
    <h1>Chapter 1</h1>
    <p>First chapter content...</p>

    <PageBreak />

    <h1>Chapter 2</h1>
    <p>Second chapter content...</p>
  </Page>
</Document>
```

***

## NoBreak

Keeps its children together on the same page. If the content doesn't fit, it moves to the next page as a unit.

```tsx theme={null}
import { Document, Page, NoBreak } from '@pdfn/react';

<Document title="Invoice">
  <Page size="A4">
    {items.map(item => (
      <NoBreak key={item.id}>
        <h3>{item.title}</h3>
        <p>{item.description}</p>
        <p>${item.price}</p>
      </NoBreak>
    ))}
  </Page>
</Document>
```

Use this for content blocks that shouldn't be split across pages, like invoice line items or signature blocks.

***

## Thead

For tables that span multiple pages, use `Thead` to make headers repeat on each page.

```tsx theme={null}
import { Document, Page, Thead } from '@pdfn/react';

<Document title="Report">
  <Page size="A4">
    <table>
      <Thead>
        <tr>
          <th>Item</th>
          <th>Quantity</th>
          <th>Price</th>
        </tr>
      </Thead>
      <tbody>
        {items.map(item => (
          <tr key={item.id}>
            <td>{item.name}</td>
            <td>{item.quantity}</td>
            <td>${item.price}</td>
          </tr>
        ))}
      </tbody>
    </table>
  </Page>
</Document>
```

`Thead` repeats headers on each page by default. Pass `repeat={false}` to disable.

<Note>
  Standard HTML `<thead>` works but won't repeat headers across pages. Use `Thead` for multi-page tables.
</Note>

<Tip>
  To prevent a table row from splitting across pages, use CSS: `<tr style={{ breakInside: "avoid" }}>`.
</Tip>

***

## Next steps

<CardGroup cols={2}>
  <Card title="Generate & Render" icon="file-pdf" href="/generate">
    Client setup, generate() and render() parameters
  </Card>

  <Card title="Styling" icon="paintbrush" href="/styling">
    Tailwind CSS, custom CSS, and inline styles
  </Card>
</CardGroup>
