Rendral

Stack · Laravel

Generate PDFs in Laravel

Blade renders your invoice or report perfectly in the browser. Then dompdf mangles the layout because it doesn't support flexbox or grid, and Browsershot wants Node plus a Chrome install on every PHP box — including the queue workers.

Render the Blade view you already have, POST the HTML, and return the bytes as a response. Full modern CSS, and nothing extra in your deploy.

01Call it from Laravel

render.ts
<?php
use Illuminate\Support\Facades\Http;

class InvoiceController extends Controller
{
    public function download(Invoice $invoice)
    {
        $html = view('invoices.show', compact('invoice'))->render();

        $pdf = Http::withToken(config('services.rendral.key'))
            ->timeout(60)
            ->post('https://rendral.com/api/v1/pdf', [
                'html' => $html,
                'options' => ['format' => 'A4', 'pageNumbers' => true],
            ])
            ->throw()
            ->body();

        return response($pdf, 200, [
            'Content-Type' => 'application/pdf',
            'Content-Disposition' => 'attachment; filename="invoice.pdf"',
        ]);
    }
}

Frequently asked

How is this different from dompdf?

dompdf implements a limited CSS subset in PHP, so modern layout silently breaks. This renders on real headless Chrome, so the PDF matches what you see in the browser.

Why not Browsershot?

Browsershot is excellent, but it requires Node and a working Chrome on every machine that renders — app servers, queue workers, CI. That is the infrastructure this removes.

Where should the API key live?

In config/services.php backed by an env var, exactly like any other credential. Never inline it in a Blade view.

Can I generate PDFs from a queued job?

Yes, and for bulk work you should. Dispatch a job and call the API from handle(); add an Idempotency-Key so a retried job returns the same document instead of billing twice.

Related

Start rendering in minutes.

A free tier, five endpoints, and SDKs for Node and Python.