import { pageMetadata } from "@/lib/page-metadata" export const metadata = pageMetadata("docs/api/react-pdf") # @json-render/react-pdf PDF document renderer. Turn JSON specs into PDFs using `@react-pdf/renderer`. ## Install ```bash npm install @json-render/core @json-render/react-pdf ``` See the [React PDF example](https://github.com/vercel-labs/json-render/tree/main/examples/react-pdf) for a full working example. ## schema The PDF element schema for document specs. Use with `defineCatalog` from core. ```typescript import { defineCatalog } from '@json-render/core'; import { schema, standardComponentDefinitions } from '@json-render/react-pdf'; const catalog = defineCatalog(schema, { components: standardComponentDefinitions, }); ``` ## Render Functions Server-side functions for producing PDF output. All accept a spec and optional `RenderOptions`. ```typescript import { renderToBuffer, renderToStream, renderToFile } from '@json-render/react-pdf'; const buffer = await renderToBuffer(spec); const stream = await renderToStream(spec); stream.pipe(res); await renderToFile(spec, './output.pdf'); ``` ### RenderOptions ```typescript interface RenderOptions { registry?: ComponentRegistry; includeStandard?: boolean; // default: true state?: Record; } ```
Option Description
registry Custom component map (merged with standard components)
includeStandard Include built-in standard components (default: true)
state Initial state for $state / $cond dynamic prop resolution
## defineRegistry Create a type-safe component registry from a catalog. Components receive `{ props, children, emit, bindings, loading }`. ```tsx import { defineRegistry } from '@json-render/react-pdf'; import { View, Text } from '@react-pdf/renderer'; const { registry } = defineRegistry(catalog, { components: { Badge: ({ props }) => ( {props.label} ), }, }); const buffer = await renderToBuffer(spec, { registry }); ``` ## createRenderer Create a standalone renderer component wired to state, actions, and validation. ```typescript import { createRenderer } from '@json-render/react-pdf'; const PDFRenderer = createRenderer(catalog, components); ``` ```typescript interface CreateRendererProps { spec: Spec | null; state?: Record; onAction?: (actionName: string, params?: Record) => void; onStateChange?: (path: string, value: unknown) => void; loading?: boolean; fallback?: ComponentRenderer; } ``` ## Renderer The main component that renders a spec to `@react-pdf/renderer` elements. ```typescript interface RendererProps { spec: Spec | null; registry?: ComponentRegistry; includeStandard?: boolean; // default: true loading?: boolean; fallback?: ComponentRenderer; } ``` ## Standard Components ### Document Structure #### Document Top-level PDF wrapper. Must be the root element. Children must be `Page` components. ```typescript { title: string | null; author: string | null; subject: string | null; } ``` #### Page A page in the document with configurable size, orientation, and margins. ```typescript { size: "A4" | "A3" | "A5" | "LETTER" | "LEGAL" | "TABLOID" | null; orientation: "portrait" | "landscape" | null; marginTop: number | null; marginBottom: number | null; marginLeft: number | null; marginRight: number | null; backgroundColor: string | null; } ``` ### Layout #### View Generic container with padding, margin, background, border, and flex alignment. ```typescript { padding: number | null; paddingTop: number | null; paddingBottom: number | null; paddingLeft: number | null; paddingRight: number | null; margin: number | null; backgroundColor: string | null; borderWidth: number | null; borderColor: string | null; borderRadius: number | null; flex: number | null; alignItems: "flex-start" | "center" | "flex-end" | "stretch" | null; justifyContent: "flex-start" | "center" | "flex-end" | "space-between" | "space-around" | null; } ``` #### Row Horizontal flex layout with optional wrapping. ```typescript { gap: number | null; alignItems: "flex-start" | "center" | "flex-end" | "stretch" | null; justifyContent: "flex-start" | "center" | "flex-end" | "space-between" | "space-around" | null; padding: number | null; flex: number | null; wrap: boolean | null; } ``` #### Column Vertical flex layout. ```typescript { gap: number | null; alignItems: "flex-start" | "center" | "flex-end" | "stretch" | null; justifyContent: "flex-start" | "center" | "flex-end" | "space-between" | "space-around" | null; padding: number | null; flex: number | null; } ``` ### Content #### Heading h1-h4 heading text with configurable color and alignment. ```typescript { text: string; level: "h1" | "h2" | "h3" | "h4" | null; color: string | null; align: "left" | "center" | "right" | null; } ``` #### Text Body text with full styling control. ```typescript { text: string; fontSize: number | null; color: string | null; align: "left" | "center" | "right" | null; fontWeight: "normal" | "bold" | null; fontStyle: "normal" | "italic" | null; lineHeight: number | null; } ``` #### Image Image from a URL with optional dimensions and fit. ```typescript { src: string; width: number | null; height: number | null; objectFit: "contain" | "cover" | "fill" | "none" | null; } ``` #### Link Hyperlink with visible text. ```typescript { text: string; href: string; fontSize: number | null; color: string | null; } ``` ### Data #### Table Data table with typed columns and string rows. Supports header styling and striped rows. ```typescript { columns: { header: string; width?: string; align?: "left" | "center" | "right" }[]; rows: string[][]; headerBackgroundColor: string | null; headerTextColor: string | null; borderColor: string | null; fontSize: number | null; striped: boolean | null; } ``` #### List Ordered or unordered list. ```typescript { items: string[]; ordered: boolean | null; fontSize: number | null; color: string | null; spacing: number | null; } ``` ### Decorative #### Divider Horizontal line separator. ```typescript { color: string | null; thickness: number | null; marginTop: number | null; marginBottom: number | null; } ``` #### Spacer Empty vertical space. ```typescript { height: number | null; } ``` ### Page-Level #### PageNumber Renders current page number and total pages. Format uses `{pageNumber}` and `{totalPages}` placeholders. ```typescript { format: string | null; // default: "{pageNumber} / {totalPages}" fontSize: number | null; color: string | null; align: "left" | "center" | "right" | null; } ``` ## Server-Safe Import Import schema and catalog definitions without pulling in React or `@react-pdf/renderer`: ```typescript import { schema, standardComponentDefinitions } from '@json-render/react-pdf/server'; ``` ## Sub-path Exports
Export Description
@json-render/react-pdf Full package: schema, renderer, components, render functions
@json-render/react-pdf/server Schema and catalog definitions only (no React)
@json-render/react-pdf/catalog Standard component definitions and types
@json-render/react-pdf/render Server-side render functions only
## Types
Export Description
ReactPdfSchema Schema type for PDF specs
ReactPdfSpec Spec type for PDF documents
RenderOptions Options for render functions
ComponentContext Typed component render function context
ComponentFn Component render function type
StandardComponentDefinitions Type of the standard component definitions object
StandardComponentProps<K> Inferred props type for a standard component by name