Laravel Blade to PDF

Keep the view you already built.
Render it as a production PDF.

Use your existing Blade templates, Laravel data, CSS, images, and fonts. BladePDF moves the browser and asset-delivery work out of the application runtime.

Existing Blade views Tailwind and print CSS Local images and fonts
InvoiceController.php php
return BladePDF::fromView('pdf.invoice', [
    'invoice' => $invoice,
    'company' => $company,
])
    ->withFooter('pdf.partials.footer')
    ->showBackground()
    ->render()
    ->download('invoice.pdf');
Blade
stays local
Assets
move safely
Chromium
is managed
Blade is not the hard part

The browser must see the same document your app sees.

A Blade view can reference private logos, generated charts, compiled stylesheets, font files, and storage-backed images that work perfectly inside the Laravel application. A separate browser process or remote renderer cannot automatically access those local files.

BladePDF renders the view inside Laravel, discovers the referenced assets in the resulting HTML and CSS, attaches them to the render request, and rewrites their URLs before Chromium loads the document.

Keep Blade logic local

Continue using loops, conditionals, translations, helpers, model data, and application services before the render leaves your app.

Keep document assets private

Use normal local asset references without publishing logos, fonts, or tenant files to an open bucket.

Use browser-quality layout

Modern CSS, print styles, backgrounds, custom fonts, and JavaScript on eligible plans render through Chromium.

Working example

A Blade file and one controller action.

The view stays in resources/views. The controller sends its rendered output and automatically resolved assets to BladePDF.

Terminal bash
composer require bladepdf/laravel
resources/views/pdf/invoice.blade.php blade
<link rel="stylesheet" href="{{ asset('css/invoice.css') }}">

<header>
    <img src="{{ asset('images/logo.svg') }}" alt="Acme">
    <h1>Invoice {{ $invoice->number }}</h1>
</header>

@foreach ($invoice->items as $item)
    <div class="line-item">
        <span>{{ $item->description }}</span>
        <strong>{{ $item->formattedAmount() }}</strong>
    </div>
@endforeach
app/Http/Controllers/InvoiceController.php php
return BladePDF::fromView('pdf.invoice', [
    'invoice' => $invoice->load('items'),
])
    ->templateName('Invoice')
    ->reference($invoice->uuid)
    ->format('A4')
    ->showBackground()
    ->render()
    ->download("invoice-{$invoice->number}.pdf");
Optional header and footer php
BladePDF::fromView('pdf.report', $data)
    ->withHeader('pdf.partials.header', $data)
    ->withFooter('pdf.partials.footer', $data)
    ->margins(18, 12, 18, 12, 'mm')
    ->render()
    ->response('report.pdf');
Implementation note. Use showBackground() when color blocks, background images, and print backgrounds are part of the design. Headers and footers are separate Chromium page chrome and have their own layout constraints.
Make Blade reachable

Self-hosted browsers and managed rendering solve assets differently.

The HTML is only useful when its styles, images, fonts, and nested references are available to the renderer.

Self-hosted or self-integrated

Self-hosted approach

A local browser may load application URLs, file paths, embedded data, or mounted assets, but your team owns the environment and its security boundary.

  • Install Chrome and Node.js or operate a separate render service
  • Make every referenced file reachable from the browser process
  • Configure authentication, URL access, filesystem mounts, or embedding
  • Scale browser workers and diagnose missing assets in production
Managed

BladePDF approach

The Laravel package converts local files into request-scoped assets so the managed browser can render the same visual document without public URLs.

  • Scan HTML attributes, inline CSS, style blocks, CSS files, and srcset
  • Resolve nested CSS url() and @import references
  • Upload attached files and rewrite them to asset:/// references
  • Record asset counts, uploads, cache hits, and timings with the render
Automatic asset pipeline

Local references become a portable render request.

The conversion happens after Blade has produced HTML and before the managed browser opens the document.

01

Render the view

Laravel compiles Blade with your data. fromView() receives a normal view name and data array, just like the rest of your application.

02

Scan and attach files

Public paths, local application hosts, filesystem paths, responsive images, stylesheets, fonts, and nested CSS dependencies are resolved.

03

Print in Chromium

The managed browser receives portable HTML and request assets, waits for configured readiness, and produces the PDF using your page options.

Reference behavior

What happens to common Blade assets?

The automatic pipeline handles common local references. You can disable it or attach assets manually when a document needs explicit control.

Capability In the Blade view BladePDF behavior
Local image {{ asset('images/logo.png') }} Resolved from the Laravel public path, uploaded, and rewritten
Compiled stylesheet {{ asset('build/assets/invoice.css') }} Attached; nested fonts and background images are scanned
Storage image {{ url('storage/qrcodes/42.png') }} Treated as local when the host matches configured local hosts
Inline CSS URL style="background:url(...)" Local URL is resolved and rewritten
Remote URL https://cdn.example.com/chart.png Preserved; network access depends on the plan and request controls
Explicit asset asset:///tenant-logo.png Attach with withAsset() or override a cloud asset for one render

Automatic resolution can be disabled globally or per render. Manual withAsset() and overrideAsset() attachments still work when scanning is disabled.

Design and architecture limits

A PDF is a print surface, not a browser tab.

BladePDF is a strong fit when

  • The document already exists as a Blade view or can share Laravel view components.
  • Modern CSS, local fonts, branded assets, and consistent Chromium output matter.
  • The deploy environment should not carry a browser runtime.
  • Private asset delivery and production render observability need a standard solution.

Choose another approach when

  • The document must render without any outbound network access.
  • A simple DOMPDF-compatible layout avoids the need for a browser entirely.
  • You need arbitrary page automation rather than a constrained PDF rendering API.
  • The document is better authored as a dashboard-managed template than application Blade.

BladePDF tradeoffs

  • ! Hosted rendering processes the final HTML and attached document assets outside your app.
  • ! Print CSS, explicit page breaks, and header/footer constraints still require document-specific design.
  • ! JavaScript and external internet access depend on the selected plan.
  • ! All renders are subject to capacity, payload, time, PDF-size, storage, and bandwidth limits.
FAQ

Questions teams ask before choosing the renderer.

Can I use an existing Blade template?
Yes. fromView() renders the selected local view inside Laravel with the data you pass, then sends the resulting HTML and resolved assets to BladePDF.
Does Tailwind CSS work?
Yes. Reference your compiled stylesheet or include the required CSS in the document. The asset pipeline can attach local stylesheets and their nested font or image references.
Do images need to be public?
No. Local images and other referenced files can be attached to the render request automatically. They do not need an open bucket or a permanent public URL.
Can the PDF have a separate header and footer?
Yes. Local view and raw HTML renders support header and footer Blade views or HTML. Chromium page header and footer areas have stricter CSS and sizing constraints than the main document.

Use the Blade view already in your codebase.

Start with one invoice, report, or certificate and keep the rest of the application flow unchanged.

$ composer require bladepdf/laravel