PDF Generation in Next.js 15 with Puppeteer
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:
Accepts
htmlContent
via a POST request.Uses Puppeteer to render the HTML and generate a PDF.
Returns the generated PDF as a downloadable file.
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. 🚀
Written by Sagar Sangwan
👨💻 Programmer | ✈️ Love Traveling | 🍳 Enjoy Cooking | Building cool tech and exploring the world!
View more blogs by me CLICK HERE
Loading related blogs...
SUBSCRIBE to Newsletter
In this newsletter we provide latest news about technology, business and startup ideas. Hope you like it.