> ## 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.

# Dev Workflow

> Run npx pdfn dev to start a local preview server with hot reload. Edit your React templates and see PDF changes instantly in the browser.

No API key, no cloud setup. The dev server runs locally with embedded Puppeteer so you can iterate on templates before deploying.

```bash theme={null}
npx pdfn dev
```

This opens a preview UI at `http://localhost:3456`.

| Flag     | Default | Description                         |
| -------- | ------- | ----------------------------------- |
| `--port` | `3456`  | Port for the dev server             |
| `--open` | —       | Open browser automatically          |
| `--mode` | —       | Load additional `.env.[mode]` files |

## How it works

The dev server runs inside your project context:

* **Your dependencies work** — import dayjs, lodash, or any package from `node_modules`
* **Your path aliases work** — `@/components/...` resolves from your `tsconfig.json`
* **Isolated Tailwind styles** — `pdfn-templates/styles.css` is auto-detected, separate from your app's styles

The preview UI shows all top-level `.tsx` files in your templates directory with zoom controls (fit-to-window or 100%).

## Template directory

By default, pdfn looks for templates in `pdfn-templates/` at your project root:

```text theme={null}
your-project/
├── pdfn-templates/
│   ├── invoice.tsx
│   ├── receipt.tsx
│   ├── styles.css
│   └── components/
│       └── Header.tsx
├── next.config.ts
└── package.json
```

Only top-level `.tsx` files appear in the preview sidebar. Files are excluded if they:

* Are inside subdirectories (e.g., `components/Header.tsx`)
* Start with `_` (e.g., `_utils.tsx`, `_shared.tsx`)

## PreviewProps for dev preview

Templates use a static `PreviewProps` property to provide sample data for the dev server preview:

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

interface InvoiceProps {
  number: string;
  customer: string;
  total: number;
}

function Invoice({ number, customer, total }: InvoiceProps) {
  return (
    <Document title={`Invoice ${number}`}>
      <Page size="A4" margin="1in">
        {/* template content */}
      </Page>
    </Document>
  );
}

Invoice.PreviewProps = {
  number: 'INV-001',
  customer: 'Acme Corp',
  total: 148,
} satisfies InvoiceProps;

export default Invoice;
```

This pattern keeps props required (better type safety) while providing sample data that the dev server uses automatically.

## Production usage

In production, pass actual data as props when calling `generate()`:

```tsx app/api/invoice/route.tsx theme={null}
import { pdfn } from '@pdfn/react';
import Invoice from '@/pdfn-templates/invoice';

const client = pdfn();

export async function GET(request: Request) {
  // Fetch real data from your database
  const invoiceData = await db.invoices.findUnique({ where: { id: '123' } });

  // Pass data as props — PreviewProps is ignored in production
  const { data, error } = await client.generate({
    react: <Invoice
      number={invoiceData.number}
      customer={invoiceData.customer}
      total={invoiceData.total}
    />,
  });

  if (error) {
    return Response.json({ error: error.message }, { status: 500 });
  }

  return new Response(data.buffer, {
    headers: { 'Content-Type': 'application/pdf' },
  });
}
```

**Key points:**

* `PreviewProps` is only used by the dev server (`pdfn dev`) for preview
* In production, you pass props directly to the component like any React component
* Props are required in the interface, so TypeScript ensures you pass all necessary data

## Debug overlays

You can enable visual overlays for grid, margins, headers, and page breaks to debug layout issues. See [Generate & Render](/generate#debug-options) for all options.

## FAQ

<AccordionGroup>
  <Accordion title="How do I add sample data for preview?">
    Use the `PreviewProps` static property on your template component. The dev server uses this data automatically. See [PreviewProps for dev preview](#previewprops-for-dev-preview).
  </Accordion>

  <Accordion title="How do I exclude files from the template list?">
    Two options:

    * **Subdirectory**: Put shared components in `pdfn-templates/components/`
    * **Underscore prefix**: Name files with `_` prefix (e.g., `_utils.tsx`, `_shared.tsx`)

    Both are excluded from the preview sidebar.
  </Accordion>

  <Accordion title="What files are recognized as templates?">
    A file appears in the preview sidebar if it:

    * Is a `.tsx` file in the root of `pdfn-templates/`
    * Has a default export (component function)
    * Imports `Document` or `Page` from `@pdfn/react`
    * Does not start with `_`
  </Accordion>

  <Accordion title="Why don't my images or fonts work in production?">
    pdfn Cloud renders PDFs on remote servers that cannot access your local filesystem. Use absolute URLs for images and Google Fonts instead of local files. See [Styling — Images](/styling#images) and [Styling — Fonts](/styling#fonts).
  </Accordion>
</AccordionGroup>

***

## Next steps

<CardGroup cols={2}>
  <Card title="Components" icon="cube" href="/components">
    Document, Page, and layout components
  </Card>

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