pdfkarim
v0.1.1
Published
Pixel-Perfect React/Next.js to A4 PDF Generator
Maintainers
Readme
PdfKarim
Pixel-Perfect React/Next.js to A4 PDF Generator
📋 Overview
PdfKarim is an open-source NPM package that enables developers to export React.js and Next.js components as pixel-perfect, searchable, multi-page A4 PDFs with repeatable headers/footers and full i18n support.
Key Benefits
- Exact CSS/HTML fidelity via headless-Chrome (Puppeteer)
- Selectable, searchable text (no raster images)
- Multi-page documents with consistent headers/footers
- Supports any language, including RTL and CJK
✨ Features
Core Features
- A4 page sizing & configurable margins (@page)
- Multi-page support: honors CSS page-break-*
- Repeatable header/footer: React components injected per page
- Searchable text: HTML text preserved
- Internationalization: UTF-8, RTL support
- JS & TS: delivers .js, .d.ts
- Hidden rendering via visible prop
- Pluggable storage: Blob, Buffer, or custom handlers (S3, email)
Non-Functional Features
- Performance: concurrent renders, asset caching
- Bundle size: core < 100 KB (Puppeteer separate)
- Compatibility: Node ≥14, React ≥16, Next.js ≥10
- Security: input sanitization, render timeouts
- Testing: 90%+ coverage (Jest)
- Docs & examples: Storybook, CodeSandbox
🚀 Installation
npm install pdfkarim puppeteer --save
# or
yarn add pdfkarim puppeteer🔧 Setup
Next.js API Route
Create an API route at pages/api/pdfkarim/render.js:
import { renderPdf } from 'pdfkarim/server';
export default async (req, res) => {
const { html, options } = req.body;
try {
const buffer = await renderPdf(html, options);
res.setHeader('Content-Type', 'application/pdf');
res.send(buffer);
} catch (err) {
res.status(500).json({ error: err.message });
}
};
// Increase the limit of the request body for large HTML content
export const config = {
api: {
bodyParser: {
sizeLimit: '10mb',
},
},
};📖 Usage
import { useRef } from 'react';
import { PdfKarim } from 'pdfkarim';
export default function MyComponent() {
const pdfRef = useRef();
const handleGeneratePdf = async () => {
// Generate and download PDF
await pdfRef.current.save('document.pdf');
};
return (
<div>
<button onClick={handleGeneratePdf}>Generate PDF</button>
<PdfKarim
ref={pdfRef}
visible={false}
header={<MyHeader />}
footer={<MyFooter />}
margins={{ top: 15, right: 15, bottom: 15, left: 15 }}
>
<MyContent />
</PdfKarim>
</div>
);
}📚 API Reference
<PdfKarim> Component
interface PdfKarimProps {
visible?: boolean; // default: false
pageSize?: 'A4' | { width: number; height: number }; // mm
margins?: { top: number; right: number; bottom: number; left: number }; // mm
header?: ReactNode; // rendered on each page
footer?: ReactNode; // rendered on each page
timeoutMs?: number; // render timeout
onComplete?: (info: { totalPages: number }) => void;
children: ReactNode;
}
interface PdfKarimHandle {
save(fileName?: string): Promise<Blob>;
getBlob(): Promise<Blob>;
getBuffer(): Promise<Buffer>;
}Props
- visible: Controls visibility of the component (defaults to
false, which renders off-screen) - pageSize: Either 'A4' or custom dimensions in mm
- margins: Page margins in mm
- header: Component to render as header on each page
- footer: Component to render as footer on each page
- timeoutMs: PDF generation timeout in milliseconds
- onComplete: Callback fired when PDF generation completes
- children: Content to render in the PDF
Methods
- save(fileName): Generates PDF and triggers download
- getBlob(): Returns PDF as a Blob
- getBuffer(): Returns PDF as a Buffer (Node.js only)
🛠️ Architecture
PdfKarim uses a client-server architecture:
- The client-side React component captures and serializes DOM content
- The server-side Puppeteer service renders the HTML to a PDF
- The generated PDF is returned to the client
📖 Documentation
For more detailed information, see the following documentation:
- Installation Guide - Detailed installation instructions
- Usage Guide - Comprehensive usage examples and best practices
- Example Project - A working Next.js demo project
🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
📄 License
MIT
