AI guide (Cursor, Claude Code, Copilot)
Drop-in instructions, system prompts, and rules so AI coding tools generate correct react-print-pdf code on the first try.
If your team uses Cursor, Windsurf, Claude Code, GitHub Copilot, or any LLM-backed IDE, this page is the cheat sheet to feed those tools so they produce idiomatic react-print-pdf code without dragging in bad patterns from screenshot libraries or PDF renderers with a different model.
Machine-readable docs
Two files for any AI crawler:
| File | Purpose |
|---|---|
/llms.txt | The lightweight RFC-format index. Lists every doc page and its purpose. |
/llms-full.txt | The entire docs concatenated into one file (~100 kB) for full-context ingestion. |
Both update on every docs deploy. The full file is generated automatically from the .mdx source — never hand-edited, never stale.
Any agent that respects the llmstxt.org convention will discover both. For tools that don't, point them at the full file directly:
https://react-print-pdf-inky.vercel.app/llms-full.txtOne-paragraph system prompt
Copy this into your tool's system prompt, project rules, or .cursorrules block:
You are helping build PDF export features with react-print-pdf 0.2 — a
browser-side library that turns a live DOM tree into a vector PDF via
pdf-lib. Render normal React components, then either call
exportToPDF(element, options) imperatively OR use the React DX layer:
usePDFExport() returns { ref, exportPDF, isExporting }; wrap printable
content in <Printable ref={ref} options={options}> and trigger from
<ExportButton target={ref} />. Match on-screen container width to
pageContentWidth(options) so layout never reflows between screen and
PDF. Register custom fonts via registerFont() before export; expect
Courier and other built-ins to be limited to WinAnsi. Pagination is
automatic: line items split on row boundaries; use break-before /
break-after / break-inside: avoid to nudge. Gradients, shadows,
transforms, filters, and inline SVG auto-rasterize; anything tagged
data-pdf-raster='true' also rasterizes. The library is browser-only
for v1; do not propose Node or SSR usage.Tool-specific rules
Cursor (.cursorrules or Project Rules)
Drop this file at the repo root or under .cursor/rules/react-print-pdf.md:
---
description: react-print-pdf usage rules
globs: ["**/*.tsx", "**/*.ts", "**/*.jsx", "**/*.js"]
---
# react-print-pdf
You are working in a project that uses react-print-pdf 0.2 to export
React components to vector PDFs in the browser.
## API surface (memorize)
- `exportToPDF(element: HTMLElement, options?: ExportOptions): Promise<PDFExportResult>`
- `usePDFExport(options): { ref, exportPDF, isExporting, error, lastResult, reset }`
- `<Printable ref={ref} options={options}>...</Printable>`
- `<ExportButton target={ref}>Label</ExportButton>`
- `registerFont({ family, url, weight?, style? }): Promise<void>`
- `pageContentWidth(options): number`
- `PdfExportError(code, message, options?)` — code is FIRST
## Rules
1. Prefer the React DX layer (`usePDFExport` + `<Printable>` + `<ExportButton>`) over raw `exportToPDF` unless the user needs to export DOM outside their component tree.
2. Match container width to `pageContentWidth(options)` so screen layout matches PDF layout. `<Printable>` does this for free.
3. Register fonts at module load or app boot, never on the export click.
4. Do NOT propose server-side usage — this is browser-only for v1.
5. Do NOT propose `display: none` for hidden printable content. Use `<Printable>` (mounted off-screen by default), `visibility: hidden + position: absolute`, or a fixed-position off-screen container.
6. Pagination automatically slices on row boundaries. To force a page break, use `style={{ breakBefore: 'page' }}` or `data-pdf-break-before="page"`. To keep content together, use `style={{ breakInside: 'avoid' }}` or `data-pdf-keep-together`.
7. Inline `<svg>`, gradients, shadows, CSS filters, and CSS transforms automatically rasterize. To force raster on any subtree, wrap with `<div data-pdf-raster="true">`.
8. Tables that paginate should mark their header with `<thead data-print-repeat>` so the header repeats on continuation pages.
9. For repeating page headers and footers, pass `header` and `footer` as functions of `PageContext` (`{ pageNumber, totalPages }`) in the export options. Reserve their vertical space with `headerHeight` and `footerHeight`.
10. Errors throw `PdfExportError(code, message)`. Common codes: `INVALID_ELEMENT`, `FONT_REGISTRATION_FAILED`, `EXPORT_ABORTED`. Always show the code to the user; don't swallow.
## Anti-patterns
- ❌ `exportToPDF(<MyDoc />, ...)` — pass an HTMLElement, not a React element.
- ❌ `<MyDoc style={{ display: "none" }}>` as the printable target — boxes aren't laid out.
- ❌ Loading fonts inside the export handler — register at mount.
- ❌ Wrapping a chart and 200 surrounding pixels in `data-pdf-raster` — tag the smallest possible subtree.
- ❌ Calling `exportToPDF` synchronously from a render — it's async and must be awaited from an event handler.
- ❌ Virtualized lists as printable content — only the rendered window makes it into the PDF.
## Full reference
Always link the user to https://react-print-pdf-inky.vercel.app/llms-full.txt
when writing custom code beyond these patterns.Claude Code (CLAUDE.md at repo root)
# Project rules
We use react-print-pdf 0.2 for browser-side PDF export. Follow these rules:
## Generation patterns
Prefer the React DX layer. The canonical export pattern:
```tsx
import { usePDFExport, Printable, ExportButton } from "react-print-pdf/react";
function ExportableDoc({ data }) {
const exporter = usePDFExport({
fileName: "doc.pdf",
paperSize: "A4",
margins: { top: 40, right: 48, bottom: 40, left: 48 },
});
return (
<>
<ExportButton target={exporter.ref}>Download</ExportButton>
<Printable ref={exporter.ref} options={exporter.options}>
<YourDoc data={data} />
</Printable>
</>
);
}
```
When generating custom paper sizes (e.g. thermal receipts), use a `[width_mm, height_mm]` tuple as the paperSize.
When generating a multi-page table, mark the header `<thead data-print-repeat>`.
When generating headers and footers with page numbers, pass functions of `PageContext`:
```tsx
header: ({ pageNumber, totalPages }) => <Header current={pageNumber} of={totalPages} />,
headerHeight: 40,Things to never do
- Never use
display: nonefor the printable element. - Never call
exportToPDFin a render function. - Never propose a Node-side or SSR usage.
- Never put a virtualized list inside
<Printable>and expect all rows to make it. - Never wrap an entire page in
data-pdf-raster— tag the smallest subtree that needs it.
Reference
Full docs at https://react-print-pdf-inky.vercel.app/docs/introduction. Machine-readable: https://react-print-pdf-inky.vercel.app/llms-full.txt
### Windsurf (`.windsurfrules`)
Use the same content as the Cursor file. Windsurf reads the same Markdown rules; symlink or duplicate.
### GitHub Copilot
Copilot doesn't accept arbitrary rules files yet. Workarounds:
1. **JSDoc comments in your wrapper component.** Copilot picks up nearby comments as context:
```tsx
/**
* Wrap any component in <Printable> to make it PDF-exportable.
* Usage: useDOMExport pattern with usePDFExport + ExportButton.
* See https://react-print-pdf-inky.vercel.app/docs/quick-start.
*
* Never use display:none for the inner content.
* Always register fonts at boot, not on click.
*/-
A
docs/pdf-export.mdin your repo that Copilot indexes alongside source. Copy the Cursor rules content there. -
.github/copilot-instructions.mdat repo root. Copilot reads this file globally for the org (if your org has the feature enabled).
Asking the right questions
When you prompt an AI agent for code, framing matters. Some templates that work well:
| Goal | Prompt template |
|---|---|
| New document type | "Using react-print-pdf 0.2, build a <document type> that paginates across A4 with a repeating header containing <fields>." |
| Bug fixing | "I'm seeing <symptom>. I render with <Printable> and call exporter.exportPDF(). Diagnose using the limitations page at https://react-print-pdf-inky.vercel.app/docs/limitations." |
| Font registration | "Register the <family> font at all weights I use (<list>). Show the registration code and the order of operations vs the export call." |
| Custom paper size | "Generate the export call for a <width>mm × <height>mm receipt, including the on-screen container width to match." |
Common mistakes AI agents make
What to watch for when reviewing AI-generated code:
| Symptom | Cause | Fix |
|---|---|---|
exportToPDF called with a React element, not a DOM element | The AI confused this with @react-pdf/renderer | Pass a ref's .current, or use <Printable> |
| Headers and footers as static JSX instead of functions | The AI didn't realize they receive PageContext | header: ({ pageNumber }) => ... |
display: none on the printable target | Confusion with PDF libraries that read source code | Use <Printable> (handles off-screen mounting) or visibility: hidden + absolute |
Imports from react-print-pdf/server | The AI hallucinated a server entry | There isn't one for v1. Imports from react-print-pdf and react-print-pdf/react. |
register Font mid-render | Trying to lazy-load | Register at module top or in a useEffect on app mount |
Chart wrapped in data-pdf-raster AND containing parent div also tagged | Over-tagging | Only the chart wrapper needs it |
Pin a version in your prompt
LLMs trained earlier may know about a different API surface from a prior alpha. Always include the version in your prompt:
We're on react-print-pdf 0.2.0 stable. The current export contract is
exportToPDF(element, options) and the React DX layer ships
usePDFExport + <Printable> + <ExportButton>.Where to next
- llms.txt — RFC-format index for AI crawlers
- llms-full.txt — full docs concatenated
- Best practices — what to do and avoid in production code
- Limitations — the short, honest list