Basic Usage
This guide demonstrates how to use EasyPdf in both visual and programmatic modes.
Visual Mode
In visual mode, you use the useEasyPdf
hook to get a reference that you can attach to your content container.
tsx
import React from "react";
import { useEasyPdf } from "@easypdf/react";
const VisualExample = () => {
const { pdfRef, downloadPDF, isDownloadingPDF, error } = useEasyPdf();
const [config, setConfig] = React.useState({
pageSize: "A4",
margins: {
top: 20,
right: 20,
bottom: 20,
left: 20,
},
styles: {
backgroundColor: "#ffffff",
defaultFontSize: 12,
defaultFontFamily: "Arial, sans-serif",
defaultTextColor: "#333333",
},
});
const handleDownload = async () => {
try {
await downloadPDF(pdfRef, {
...config,
filename: "example.pdf",
});
} catch (err) {
console.error("Failed to download PDF:", err);
}
};
return (
<div>
<button
className="btn btn-primary"
onClick={handleDownload}
disabled={isDownloadingPDF}
>
{isDownloadingPDF ? (
<>
<span className="loading loading-spinner loading-xs"></span>
Generating...
</>
) : (
"Download PDF"
)}
</button>
{error && (
<div className="alert alert-error">
<span>{error.message}</span>
</div>
)}
{/* Content container with pdfRef */}
<div
ref={pdfRef}
style={{
backgroundColor: config.styles.backgroundColor,
color: config.styles.defaultTextColor,
fontFamily: config.styles.defaultFontFamily,
fontSize: config.styles.defaultFontSize,
}}
>
<div className="p-8">
<h1 className="text-4xl font-bold mb-8">Sample PDF Document</h1>
<div className="my-6">
<img
src="https://picsum.photos/id/247/300/200"
alt="Sample image"
className="max-w-[300px] h-auto shadow-lg rounded"
crossOrigin="anonymous"
/>
</div>
<section className="space-y-6">
<h2 className="text-2xl font-bold">Content Section</h2>
<p>
This content will be rendered in the PDF. You can include text,
images, and any other HTML content that can be rendered by the
browser.
</p>
</section>
</div>
</div>
</div>
);
};
Programmatic Mode
In programmatic mode, you can generate PDFs without rendering content to the screen.
tsx
import React from "react";
import { useEasyPdf } from "@easypdf/react";
const ProgrammaticExample = () => {
const {
createPDFBlob,
downloadPDF,
viewPDF,
isCreatingBlob,
isDownloadingPDF,
error,
} = useEasyPdf();
const content = (
<div className="pdf-document">
<h1>Programmatically Generated PDF</h1>
<p>Generated at: {new Date().toLocaleString()}</p>
<div className="sample-section">
<h2>Dynamic Content</h2>
<p>This PDF was generated using the programmatic API.</p>
</div>
</div>
);
const handleGeneratePDF = async () => {
try {
const blob = await createPDFBlob(content, {
pageSize: "A4",
margins: {
top: 20,
right: 20,
bottom: 20,
left: 20,
},
styles: {
backgroundColor: "#ffffff",
defaultFontSize: 12,
defaultFontFamily: "Arial, sans-serif",
defaultTextColor: "#333333",
},
});
if (blob) {
// View the PDF in a new tab
await viewPDF(blob);
// Or download it
await downloadPDF(blob, {
filename: "generated.pdf",
});
}
} catch (err) {
console.error("Failed to generate PDF:", err);
}
};
return (
<div>
<div className="flex flex-wrap gap-4">
<button
className="btn btn-primary"
onClick={handleGeneratePDF}
disabled={isCreatingBlob || isDownloadingPDF}
>
{isCreatingBlob ? "Generating..." : "Generate PDF"}
</button>
</div>
{error && (
<div className="alert alert-error">
<span>{error.message}</span>
</div>
)}
</div>
);
};
Configuration
Both modes accept the same configuration options. Here's an example with common settings:
tsx
const config = {
// Page Configuration
pageSize: "A4",
margins: {
top: 20,
right: 20,
bottom: 20,
left: 20,
},
// Metadata
metadata: {
title: "Generated Document",
author: "Your Name",
subject: "Document Subject",
keywords: ["pdf", "document"],
creator: "EasyPdf Generator",
},
// Watermark (optional)
watermark: {
text: "CONFIDENTIAL",
fontSize: 60,
color: "#FF0000",
opacity: 0.2,
angle: -45,
},
// Styling
styles: {
backgroundColor: "#ffffff",
defaultFontSize: 12,
defaultFontFamily: "Arial, sans-serif",
defaultTextColor: "#333333",
customCSS: ".custom-class { font-weight: bold; }",
},
};
Best Practices
Error Handling
tsxtry { await downloadPDF(pdfRef, config); } catch (error) { console.error("PDF generation failed:", error); // Show user-friendly error message }
Loading States
tsx<button className="btn btn-primary" disabled={isDownloadingPDF}> {isDownloadingPDF ? ( <> <span className="loading loading-spinner loading-xs"></span> Generating... </> ) : ( "Download PDF" )} </button>
Image Handling
- Use
crossOrigin="anonymous"
for external images - Ensure images are loaded before PDF generation
tsx<img src="https://example.com/image.jpg" crossOrigin="anonymous" alt="Description" className="max-w-[300px] h-auto" />
- Use
Styling
- Use pixel units for consistent rendering
- Apply styles through the config object
- Consider print-friendly colors
- Test with different content lengths
Performance
- Optimize images before including
- Use appropriate scale factor (default: 2)
- Test with representative content volume