Converting HTML to PDF in Laravel 10 Using Puppeteer (Full Guide)

convert html to pdf

Generating PDF files from HTML is a very common requirement in web applications. Whether you’re building an invoicing system, creating reports, or generating user-related documentation, you’ll often need a reliable way to turn HTML into a well-formatted PDF.

While packages like Laravel DOMPDF or Browsershot are commonly used, they sometimes fail when dealing with complex layouts, CSS, or JavaScript. In such cases, Puppeteer (a Node.js library that controls Headless Chrome) provides a much more powerful and reliable solution.

In this guide, we’ll cover how to integrate Puppeteer into a Laravel 10 application to convert HTML to PDF. We’ll also explore an alternative using DomPDF for simpler use cases.

Why Use Puppeteer?

Unlike PHP-only libraries (DomPDF, Snappy, etc.), Puppeteer uses Headless Chrome, meaning your PDF will look almost identical to how it appears in a real browser. This makes it ideal for complex designs like invoices, dashboards, or custom reports.

Requirements

Before starting, ensure you have the following installed:

  • Laravel 10 (or latest version)
  • Node.js (Puppeteer requires Node.js)
  • Composer (to install PHP-based alternatives like DomPDF)

Step 1: Install Puppeteer

Navigate to your Laravel project root and install Puppeteer via npm:

npm install puppeteer

Step 2: Create a Puppeteer Script

Inside your Laravel project, create a file at:

resources/js/GeneratePDF.js

This script will handle the Puppeteer logic for converting HTML into PDF.

// resources/js/GeneratePDF.js

const puppeteer = require("puppeteer");

(async () => {
    try {
        // Capture arguments (HTML file path and output file path)
        const args = process.argv.slice(2);
        const htmlFile = args[0];
        const pdfFile = args[1];

        const browser = await puppeteer.launch();
        const page = await browser.newPage();

        // Load HTML content
        await page.goto(`file://${htmlFile}`, { waitUntil: "networkidle0" });

        // Generate PDF
        await page.pdf({
            path: pdfFile,
            format: "A4",
            printBackground: true
        });

        await browser.close();
        console.log("PDF Generated Successfully!");
    } catch (err) {
        console.error("Error generating PDF:", err);
        process.exit(1);
    }
})();

This script takes an HTML file and outputs a PDF.

Step 3: Create a Laravel Controller

Create a controller app/Http/Controllers/GeneratePDFController.php to call the Puppeteer script from Laravel:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Process;

class GeneratePDFController extends Controller
{
    public function generate(Request $request)
    {
        // Save incoming HTML content into a temporary file
        $htmlContent = $request->input('html');
        $htmlFile = storage_path('app/temp.html');
        $pdfFile = storage_path('app/output.pdf');

        file_put_contents($htmlFile, $htmlContent);

        // Call Puppeteer script
        $command = "node " . base_path("resources/js/GeneratePDF.js") . " $htmlFile $pdfFile";
        $process = Process::run($command);

        if ($process->failed()) {
            return response()->json(['error' => 'PDF generation failed'], 500);
        }

        return response()->download($pdfFile, 'document.pdf')->deleteFileAfterSend(true);
    }
}

Step 4: Add Route

In routes/web.php:

use App\Http\Controllers\GeneratePDFController;

Route::post('/generate-pdf', [GeneratePDFController::class, 'generate']);

Step 5: Test the API

You can now send a POST request to /generate-pdf with an HTML payload:

{
  "html": "<h1>Invoice #123</h1><p>This is a test PDF generated with Puppeteer in Laravel.</p>"
}

This will return a downloadable PDF.

Alternative: Using DomPDF in Laravel

If your layout is simple and doesn’t require advanced CSS/JS rendering, you can use DomPDF.

Step 1: Install DomPDF

composer require barryvdh/laravel-dompdf

Step 2: Use DomPDF in Controller

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Barryvdh\DomPDF\Facade\Pdf;

class GeneratePDFController extends Controller
{
    public function generateWithDomPDF(Request $request)
    {
        $html = $request->input('html');
        $pdf = Pdf::loadHTML($html);

        return $pdf->download('document.pdf');
    }
}

Step 3: Add Route

Route::post('/generate-pdf-dompdf', [GeneratePDFController::class, 'generateWithDomPDF']);

Choosing Between Puppeteer and DomPDF

  • Use Puppeteer if your HTML is complex (heavy CSS, charts, Tailwind, animations, etc.).
  • Use DomPDF if your layout is simple and you want a pure PHP solution without Node.js.

Conclusion

  • Puppeteer provides a powerful and modern way to generate high-quality PDFs using Headless Chrome.
  • DomPDF is lighter and works fully within PHP but has limitations with advanced layouts.

Depending on your project needs, you can choose the right solution.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top