HTML to PDF in PHP and Laravel, without the library mess
The PHP path to PDF is paved with half-working options: DomPDF can't do Flexbox or Grid, laravel-snappy wraps a binary that was archived in 2023, and Browsershot or snappdf mean installing and babysitting headless Chromium inside your Sail or Docker container. pdfkitt moves the browser to the server side — your app renders the Blade template and makes one HTTP call.
Laravel: render the view, POST it
No package to install. Render your existing Blade view to HTML, send it, store the PDF.
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Storage;
$html = view('invoices.show', ['invoice' => $invoice])->render();
$response = Http::withToken(config('services.pdfkitt.key'))
->post('https://api.pdfkitt.dev/v1/convert', [
'html' => $html,
'options' => ['page_size' => 'A4'],
]);
Storage::put("invoices/{$invoice->id}.pdf", $response->body());Plain PHP works too
Any PHP codebase that can make an HTTP request can generate PDFs — WordPress plugins, legacy apps, Symfony, anything.
$ch = curl_init('https://api.pdfkitt.dev/v1/convert');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('PDFKITT_API_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'html' => '<h1>Invoice</h1>',
'options' => ['page_size' => 'A4'],
]),
]);
file_put_contents('invoice.pdf', curl_exec($ch));
curl_close($ch);Why the usual PHP libraries struggle
Pure-PHP renderers like DomPDF re-implement a browser engine in PHP, so modern CSS — Flexbox, Grid, custom fonts, right-to-left text — renders partially or not at all. wkhtmltopdf-based packages depend on an engine that stopped receiving updates years ago. Chromium-wrapper packages fix fidelity but hand you a new problem: a full browser to install, patch, and keep alive inside every environment your app deploys to, including CI. An HTTP API keeps the fidelity and deletes the ops burden — requests hit a warm pool of Chromium instances, so typical latency is around 680ms with no cold start.
FAQ
Why not just use DomPDF or laravel-snappy?
DomPDF renders a limited subset of CSS - no Flexbox, no Grid, and right-to-left text often comes out wrong. laravel-snappy wraps wkhtmltopdf, which was archived in 2023 and is no longer maintained. Both work for simple documents; both hit a wall on real invoice and report layouts. pdfkitt renders with current Chromium, so your HTML looks the way it does in a browser.
How is this different from Browsershot or snappdf?
Browsershot and snappdf run headless Chromium on your own server, which means installing Chromium and its system dependencies inside your Docker or Sail container, keeping it patched, and debugging timeouts when it breaks. pdfkitt runs the browser on our side - your Laravel app just makes one HTTP call, so there is nothing to install and nothing to maintain.
Do CSS Grid, Flexbox, and page breaks work?
Yes. Rendering is real Chromium, so CSS Grid, Flexbox, web fonts, and print CSS such as @page and break-inside: avoid behave exactly like the browser. This is the main gap developers hit with DomPDF and wkhtmltopdf.
Does it execute JavaScript in my HTML?
No. pdfkitt renders static HTML and CSS; page JavaScript is not executed. Render your Blade or Twig template server-side and send the final HTML. If a chart is drawn client-side, render it to SVG or an image first.
Is my HTML stored anywhere?
No. HTML is processed in memory to render the PDF and is never written to storage or logs. Only request metadata such as timing and status is recorded.
Try pdfkitt free — 1,000 PDFs/month, no credit card
Get an API key and send your first PDF from Laravel in minutes.