Skip to content

§ Laravel HTML to PDF

Laravel HTML to PDF: Convert Blade Views to PDF, dompdf to API

Turn a Blade view or any URL into a pixel perfect PDF from your Laravel app with one HTTP call. Managed Chromium renders your real templates, so Tailwind, custom fonts and charts come out right, with no dompdf CSS limits and no Chromium to run in your own container. Try it on any page below.

  • Early access, launching soon
  • No card required
  • Your HTML stays yours

§ Live demo

Runs in your browser. Nothing is uploaded.

Your PDF is downloading. Want this as one API call, with the page archived too?

§ Short answer

Laravel has four real ways to convert HTML to PDF: barryvdh/laravel-dompdf for simple Blade invoices in plain CSS, spatie/laravel-pdf (Browsershot) for full Chromium fidelity, barryvdh/laravel-snappy for legacy wkhtmltopdf apps, and a hosted rendering API for zero-ops scale. The deciding question is your CSS: dompdf only understands CSS 2.1, so if your template uses Tailwind, flexbox or grid it cannot render it. For modern templates you need a real browser, which you either run yourself with Browsershot or offload to an API.

Last updated July 2026. Written and fact checked by the Sitepdf team.

§ 00

The four Laravel PDF paths, side by side

Every Laravel team lands on one of these. They differ mostly in which CSS they support and whether a browser has to live in your infrastructure.

Package or approach Engine Tailwind and modern CSS What you operate Best for
barryvdh/laravel-dompdf dompdf, pure PHP No: CSS 2.1 only, no flexbox or grid Nothing extra, it is a PHP library Simple invoices in hand written CSS, fastest in-process
spatie/laravel-pdf
Browsershot
Real Chromium via Node Full support Node and a Chromium install, kept warm Modern templates when a browser is welcome in your stack
barryvdh/laravel-snappy wkhtmltopdf, archived 2023 Partial and frozen at ~2014, unpatched CVEs The wkhtmltopdf binary Only maintaining a legacy app, not new work
Hosted rendering API
Sitepdf
Managed Chromium Full support Nothing, it is an HTTP call Modern CSS at volume with no browser in your container, plus a dated record

Engine and license facts are from each package and its upstream project. The honest split: if your invoices are plain and your CSS is simple, dompdf is the fastest, cheapest answer and you should use it. The moment Tailwind or web fonts enter the Blade template, you need a real browser, and then the only question left is whether you run it or someone else does.

§ 01

Start with dompdf, and know exactly where it stops

For a plain invoice or receipt, barryvdh/laravel-dompdf is still the right first reach. It is the most downloaded Laravel PDF package ever for a reason: it is a thin wrapper around the pure PHP dompdf library, it renders a Blade view directly, it needs no external binary and no browser, and because it skips a layout engine and a JS runtime it is the fastest in-process option you have.

use Barryvdh\DomPDF\Facade\Pdf;

$pdf = Pdf::loadView('invoices.show', ['invoice' => $invoice]);
return $pdf->download("invoice-{$invoice->id}.pdf");

The wall you hit is CSS. dompdf supports CSS 2.1 and little more, so there is no flexbox, no grid, and no utility classes. In 2026 most Laravel apps style with Tailwind, and dompdf simply cannot render a Tailwind template, the layout collapses. So the rule is clean: if you are willing to write plain, table based CSS by hand for that one document, dompdf is fast and free and you are done. If your template shares the Tailwind design system the rest of your app uses, dompdf is a dead end and you need a browser.

§ 02

Browsershot: real Chromium fidelity, if you run the browser

When the template needs a real browser, the community answer is spatie/laravel-pdf, which drives headless Chromium through Browsershot. You render a Blade view and get back a PDF that matches Chrome exactly, Tailwind, flexbox, grid, web fonts, even JavaScript charts all behave, because the same engine your users see is doing the rendering.

use Spatie\LaravelPdf\Facades\Pdf;

Pdf::view('invoices.show', ['invoice' => $invoice])
    ->format('letter')
    ->save("invoice-{$invoice->id}.pdf");

The cost lands in your infrastructure. Browsershot needs Node and a Chromium install sitting next to your PHP, so your Docker image grows and your deploy now manages a browser. Cold Chromium launches add roughly 300 to 800ms per render, which is fine for an occasional download and painful under load, so the usual fix is a queue worker that keeps a Chromium process warm. Browsershot is an excellent choice when a browser is welcome in your environment. It does not remove the browser; it commits you to operating one. The HTML to PDF in PHP guide walks through the same setup with code.

§ 03

Skip laravel-snappy for new work

If you inherit a Laravel app that makes PDFs with barryvdh/laravel-snappy, know what is under it. Snappy wraps wkhtmltopdf, and wkhtmltopdf was formally archived by its maintainer in early 2023, no more releases, several CVEs that will never be patched, and a rendering engine frozen on a years old WebKit fork whose CSS support stopped advancing around 2014. If the existing PDFs render correctly there is no emergency, but do not build new features on it and plan a migration off the binary. The full case and the safe replacements are on the wkhtmltopdf alternative page.

§ 04

The API path: modern CSS, no browser in your container

The fourth option gives you Browsershot level fidelity without putting Chromium in your app at all. A hosted rendering API runs managed Chromium on its own servers, so from Laravel it is a single HTTP request, no Node, no browser install, no memory pool to tune, and it works on managed and serverless hosts where you cannot launch a browser at all.

use Illuminate\Support\Facades\Http;

$res = Http::withToken(config('services.sitepdf.key'))
    ->asMultipart()
    ->post('https://api.sitepdf.com/v1/render', [
        ['name' => 'url',     'contents' => route('invoices.show', $invoice)],
        ['name' => 'format',  'contents' => 'Letter'],
        ['name' => 'archive', 'contents' => 'true'],
    ]);

$pdfUrl = $res->json('pdf_url');

Point it at a Blade route with route() and Chromium loads the page just as a visitor would, or post a rendered HTML string instead. That archive=true flag is the capability no local package offers: it stores a timestamped snapshot of exactly what was rendered, retrievable by id, so months later you can prove what a given invoice looked like when you produced it. For finance heavy Laravel apps that record is often the whole reason to render through an API. See the PDF generator API page for the full call and the website archiving page for how the record works.

From Laravel: render a Blade route in managed Chromium and keep a dated copy.
curl https://api.sitepdf.com/v1/render \
  -H "Authorization: Bearer $SITEPDF_KEY" \
  -F url=https://app.example.com/invoices/8842 \
  -F format=Letter \
  -F margin=normal \
  -F archive=true

{
  "pdf_url": "https://api.sitepdf.com/v1/documents/doc_2t9xc.pdf",
  "pages": 2,
  "rendered_in_ms": 1810,
  "archive": {
    "id": "arc_p33mv",
    "captured_at": "2026-07-19T18:22:41Z",
    "retrieve_url": "https://api.sitepdf.com/v1/archives/arc_p33mv"
  }
}

The API is in early access; this is the documented call shape it opens with. Full request and response walkthrough.

§ 05

Questions about this job

What is the best way to convert HTML to PDF in Laravel?
It depends on your CSS. For a simple invoice in plain CSS, barryvdh/laravel-dompdf is fastest and free. For a Tailwind or web-font template you need a real browser, either spatie/laravel-pdf with Browsershot if you can run Chromium, or a hosted rendering API if you would rather not put a browser in your container.
Why does my dompdf PDF ignore Tailwind classes?
Because dompdf only supports CSS 2.1. It has no flexbox, no grid and no understanding of Tailwind utility classes, so a Tailwind template renders as an unstyled or collapsed layout. To render a Tailwind Blade view faithfully you need a real browser engine, which means Browsershot or a Chromium based rendering API rather than dompdf.
Is laravel-snappy safe to use in 2026?
Not for new projects. laravel-snappy wraps wkhtmltopdf, which was archived in 2023 with unpatched CVEs and a rendering engine frozen around 2014. Existing apps that already work can stay for now, but do not build new features on it and plan a migration to a Chromium based renderer or a hosted API.
How do I generate a PDF in Laravel without installing Chromium?
Call a hosted rendering API. You send the URL of a Blade route or a rendered HTML string over HTTP, managed Chromium renders it on the vendor side, and you get the PDF back. Nothing runs a browser in your container, so it also works on managed and serverless hosts where you cannot launch Chromium at all.
How do I keep a copy of the Laravel PDFs I generate?
Local packages hand you the file and keep no record. A rendering API with an archive option can store a timestamped snapshot of each render, retrievable by id, so you have a dated copy of exactly what an invoice or statement looked like when you produced it. That provenance is often the reason finance and compliance teams render through an API.

§ Early access

Get on the early-access list

The API opens to the list first, in order. Early access locks the planned launch rates for 12 months. No card required, launching soon.

Render + archive, one API