PDF Generation in Next.js 15 with Puppeteer

195

Discover how to integrate Puppeteer with Next.js 15 for seamless PDF generation from HTML content. This tutorial covers setting up API routes, converting HTML to PDFs, and providing an easy way for users to download the generated documents.

Not a premium member? READ HERE

Steps to Use Puppeteer in Next.js

1. Install Puppeteer

To get started, install Puppeteer using the following command:

npm install puppeteer

2. Create an API Route for PDF Generation

For Next.js App Router (v14+), create a file in app/api/generate-pdf/route.js and add the following code:

import puppeteer from "puppeteer";

export async function POST(req) {
  try {
    const { htmlContent } = await req.json();

    // Launch Puppeteer in headless mode
    const browser = await puppeteer.launch({ headless: "new" });
    const page = await browser.newPage();

    // Set HTML content
    await page.setContent(htmlContent, { waitUntil: "domcontentloaded" });

    // Generate PDF
    const pdfBuffer = await page.pdf({ format: "A4", printBackground: true });

    await browser.close();

    return new Response(pdfBuffer, {
      headers: {
        "Content-Type": "application/pdf",
        "Content-Disposition": "attachment; filename=generated.pdf",
      },
    });
  } catch (error) {
    return new Response(JSON.stringify({ error: "PDF generation failed" }), {
      status: 500,
    });
  }
}

This API route:

3. Frontend Component to Trigger PDF Download

Add a frontend React component to trigger the PDF generation and download it.

"use client";
import { useState } from "react";

export default function GeneratePDF() {
  const [loading, setLoading] = useState(false);

  const generatePDF = async () => {
    setLoading(true);
    const htmlContent = `<h1>Hello, PDF!</h1><p>This is a PDF generated from HTML.</p>`;

    const response = await fetch("/api/generate-pdf", {
      method: "POST",
      body: JSON.stringify({ htmlContent }),
      headers: {
        "Content-Type": "application/json",
      },
    });

    if (response.ok) {
      const blob = await response.blob();
      const url = window.URL.createObjectURL(blob);
      const link = document.createElement("a");
      link.href = url;
      link.download = "generated.pdf";
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
    } else {
      alert("Failed to generate PDF");
    }
    setLoading(false);
  };

  return (
    <div className="p-4">
      <button
        onClick={generatePDF}
        className="bg-blue-500 text-white px-4 py-2 rounded"
        disabled={loading}
      >
        {loading ? "Generating..." : "Download PDF"}
      </button>
    </div>
  );
}

Restart the Next.js app:

npm run dev

🔥 Found this blog post helpful? 🔥

If you enjoyed this article and found it valuable, please show your support by clapping 👏 and subscribing to my blog for more in-depth insights on web development and Next.js!

Subscribe here: click me

Your encouragement helps me continue creating high-quality content that can assist you on your development journey. 🚀

JavaScriptNext.jsWeb DevelopmentBackendAPI
Sagar Sangwan

Written by Sagar Sangwan

Code. Write. Build. Explore. 💻✍️ Software developer by day, mechanical tinkerer by night. When I’m not shipping code or writing blogs, you’ll find me trekking up a mountain, whipping up a feast, or hitting the open road on two wheels. Life is better in high gear.

Follow

View more blogs by me CLICK HERE

Loading related blogs...

Stay Updated

Subscribe to get the latest posts delivered to your inbox