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.
To get started, install Puppeteer using the following command:
npm install puppeteer
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:
Accepts htmlContent
via a POST request.
Uses Puppeteer to render the HTML and generate a PDF.
Returns the generated PDF as a downloadable file.
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>
);
}
npm run dev
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. 🚀
👨💻 Programmer | ✈️ Love Traveling | 🍳 Enjoy Cooking | Building cool tech and exploring the world!
View more blogs by me CLICK HERE
Loading related blogs...
In this newsletter we provide latest news about technology, business and startup ideas. Hope you like it.