Skip to content

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

  1. Error Handling

    tsx
    try {
      await downloadPDF(pdfRef, config);
    } catch (error) {
      console.error("PDF generation failed:", error);
      // Show user-friendly error message
    }
  2. Loading States

    tsx
    <button className="btn btn-primary" disabled={isDownloadingPDF}>
      {isDownloadingPDF ? (
        <>
          <span className="loading loading-spinner loading-xs"></span>
          Generating...
        </>
      ) : (
        "Download PDF"
      )}
    </button>
  3. 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"
    />
  4. Styling

    • Use pixel units for consistent rendering
    • Apply styles through the config object
    • Consider print-friendly colors
    • Test with different content lengths
  5. Performance

    • Optimize images before including
    • Use appropriate scale factor (default: 2)
    • Test with representative content volume

Released under the MIT License.