Approach · craft · in production
PDFs as React Components
I render all customer-facing PDFs as React components, ensuring high-fidelity, consistent brand output directly from code, treating them as first-class product artifacts.
Customer-facing PDFs are not static documents; I build them as dynamic React components, compiled server-side, to guarantee brand consistency and high-quality output across all Total Ventures products.
What it is
This approach involves defining the structure, content, and styling of a PDF document using React components. Instead of relying on traditional methods like exporting from a word processor or using complex templating engines, I write declarative React code that describes the PDF's layout. Tools like `@react-pdf/renderer` provide a set of React primitives (e.g., `<Document>`, `<Page>`, `<View>`, `<Text>`, `<Image>`) that map directly to PDF elements. This allows me to leverage familiar component-based development patterns, including props for dynamic data and a CSS-in-JS like styling approach, to construct complex documents programmatically.
Why I do it this way
Quality is a product feature, regardless of the price tier. Using React components for PDFs ensures every document shipped reflects the brand's visual identity with pixel-perfect consistency. This eliminates manual errors, formatting drift, and the headaches associated with maintaining multiple document templates across different tools. The code-driven nature means PDFs are version-controlled alongside the rest of the application, making updates, refactoring, and auditing straightforward. It also integrates seamlessly with my Voice as Source of Truth discipline, where brand guidelines and copy are centralized and pulled directly into components, ensuring a unified voice and look across all outputs. This method provides a superior developer experience compared to wrestling with headless browser rendering inconsistencies or proprietary document generation APIs.
How it works in practice
On the frontend, I design the PDF layout using a component library. On the backend, typically a Node.js serverless function (Vercel Functions or Firebase Functions), this React component tree takes dynamic data—pulled from Firebase, Stripe webhooks, or other services—and renders it into a PDF stream. For instance, when a user purchases a guide on Pregnancy Power Hour, a Stripe webhook triggers a Firebase Function. This function fetches the user's specific data, passes it as props to the relevant React PDF component, and then streams the generated PDF to a cloud storage bucket. From there, Resend delivers it as an email attachment. For products like Inky, where content is generated and delivered as an artifact, this system is central to the Credit Packs over Subscriptions model—the generated PDF is the value delivered for a credit. Claude Code often assists in writing and refining these PDF components, mapping data structures to visual elements, which is a core part of my agentic engineering workflow. This shared generation service also supports my Multiple Revenue Streams, One Back Office strategy, allowing different products to use the same underlying PDF generation infrastructure.
Where this breaks down
While powerful, this approach has limitations. The initial setup overhead for the rendering pipeline can be higher than simply exporting a Word document. Debugging PDF layout issues can be less intuitive than debugging a web page in a browser, as the feedback loop is often tied to regenerating the PDF. For extremely complex, highly interactive layouts or very specific graphic design requirements, the primitives offered by React PDF libraries might require more creative component composition. Performance for generating a very high volume of large, complex PDFs concurrently can also be a consideration, demanding careful optimization and scaling of the serverless functions to handle CPU-intensive rendering tasks.
FAQs
- Is this overkill for simple documents?
- For basic receipts, perhaps. But for any customer-facing artifact that reflects your brand, the consistency and maintainability outweigh the initial setup. It's about treating quality as a product feature, not an afterthought.
- How do you handle complex layouts or charts?
- React-PDF offers primitives for layout. For charts, I typically generate them as images (e.g., using a charting library on the server) and embed them into the PDF component, treating them as static visual assets.
I run this and four other brands. Want to see the operator playbook in detail?
Get the Builder's Playbook →