Laravel PDF API

Your Blade views in.
Production PDFs out.

Call a Laravel-native facade, keep your existing views, and let a managed Chromium API handle assets, render capacity, storage, logs, and async delivery.

Laravel 10–13 Sync and async Private assets supported
InvoiceController.php php
return BladePDF::fromView('pdf.invoice', [
    'invoice' => $invoice,
])
    ->reference($invoice->uuid)
    ->format('A4')
    ->showBackground()
    ->render()
    ->download("invoice-{$invoice->number}.pdf");
Blade
stays local
Assets
move safely
Chromium
is managed
An API shaped for Laravel

A generic HTML endpoint is only half an integration.

A production Laravel PDF flow starts before Chromium receives HTML. Blade must render with application data, private images and fonts must reach the renderer, errors need a request id, and long-running documents need a delivery path that does not keep a web request open.

BladePDF’s Laravel package covers that full boundary. It renders local views, resolves their assets, builds the API request, returns typed results, and connects the render to logs, storage, and signed events.

Laravel-native source

Use fromView() with normal Blade data, fromHtml() with prepared markup, or fromTemplate() for dashboard-managed documents.

Typed delivery

Return an inline response, force a download, save locally, access raw bytes, or submit a stored async render.

Operational context

Correlate request ids with render history, timing metrics, failures, stored files, and webhook delivery attempts.

Real invoice example

Install once, render where the document belongs.

The synchronous flow is suitable for downloads and inline previews. Use the async flow when the result should be stored and delivered after acceptance.

Terminal bash
composer require bladepdf/laravel
.env env
BLADEPDF_API_KEY=blpdf_...
Synchronous invoice download php
return BladePDF::fromView('pdf.invoice', [
    'invoice' => $invoice,
])
    ->templateName('Invoice')
    ->reference($invoice->uuid)
    ->format('A4')
    ->showBackground()
    ->render()
    ->download("invoice-{$invoice->number}.pdf");
Asynchronous stored invoice php
$submission = BladePDF::fromView('pdf.invoice', $data)
    ->reference($invoice->uuid)
    ->storePdf()
    ->webhook(
        route('webhooks.bladepdf'),
        config('bladepdf.webhook_secret'),
    )
    ->async();
Implementation note. Async submissions require storePdf() because no PDF bytes are returned in the acceptance response. The request can still wait for an available concurrency slot before it receives 202 Accepted.
Build or buy the rendering layer

A PDF API removes a different set of work than a PDF library.

Both self-hosted and hosted approaches can be correct. The key question is whether browser operations and delivery workflows belong inside your application platform.

Self-hosted or self-integrated

Self-hosted renderer

Use Browsershot, a Spatie self-hosted driver, Gotenberg, DOMPDF, or another renderer when infrastructure control and data locality are the priority.

  • Install or deploy the rendering engine and its dependencies
  • Expose, embed, or package assets for the renderer
  • Size queues, workers, memory, retries, and timeouts
  • Build logs, storage, callbacks, and operational dashboards
Managed

BladePDF API

Use BladePDF when the Laravel team wants a narrow API boundary and a managed document workflow around Chromium.

  • Render existing Blade views through a fluent Laravel facade
  • Transfer local assets automatically with the request
  • Use managed queues, concurrency, isolation, and recovery
  • Opt into stored PDFs, signed URLs, native async, and signed webhooks
What happens to a local view

The API request is assembled for you.

The package keeps application rendering local while making the result portable to managed Chromium.

01

Blade runs in Laravel

Models and application objects stay in your code. The package renders the selected view into HTML before sending the render request.

02

Assets become request-scoped

Local src, href, srcset, CSS url(), @import, and font references are discovered, attached, and rewritten to asset:/// URLs.

03

Choose the delivery contract

Wait for PDF bytes synchronously, or store the output and handle completion through a signed asynchronous event.

Sync or async

Use the response shape that matches the product flow.

Both modes use the same render options and managed capacity. They differ in when your application receives control and where the finished file lives.

Capability Synchronous render Asynchronous render
Best for Downloads, inline previews, immediate controller responses Large documents, background workflows, post-render delivery
Finish method render() storePdf()->async()
Initial result RenderResult with PDF bytes RenderSubmission with request id and reference
PDF storage Optional Required
Completion The HTTP call returns after generation A pdf.rendered or pdf.failed event is recorded after acceptance
Delivery response(), download(), save(), bytes, or base64 Stored file, signed URL, dashboard endpoint, or per-request webhook
Capacity Uses a concurrency slot and can queue Uses the same capacity and can wait before acceptance

Native async is not a way around plan capacity. It lets the application stop waiting after the render has been validated and accepted for background processing.

Architecture choice

A hosted API is a clear operational trade.

BladePDF is a strong fit when

  • The Laravel application already owns the Blade templates and document data.
  • Production browser installs, private asset access, and worker scaling are recurring pain.
  • The product needs immediate downloads plus a path to stored and asynchronous documents.
  • Render history, failure details, request ids, and delivery logs are valuable in support.

Choose self-hosting when

  • PDF generation must continue during an internet or external-service outage.
  • Regulatory or architectural rules require all rendering to remain on your infrastructure.
  • The application needs arbitrary browser APIs beyond PDF-oriented options.
  • You already have a mature, observable browser or Gotenberg platform.

BladePDF tradeoffs

  • ! Render requests require outbound network access and valid credentials.
  • ! The hosted service processes the rendered HTML and the files attached to the request.
  • ! Free and paid plans have explicit limits; paid plans are not unlimited infrastructure.
  • ! Asynchronous rendering requires managed storage and an event-handling integration.
FAQ

Questions teams ask before choosing the renderer.

Is this only a raw REST API?
No. The Laravel package provides the fluent BladePDF:: facade, renders local Blade views, resolves assets, maps options, and returns Laravel-friendly result objects. A documented REST endpoint is available for other languages.
What happens to local images and fonts?
The package scans rendered HTML and nested CSS, attaches local files to the request, and rewrites their references to asset:/// URLs before Chromium runs. External URLs are preserved when plan and network settings allow them.
When should I use async rendering?
Use async() when the application should continue after a render is accepted rather than waiting for the PDF. Async requires storePdf() and should be paired with a dashboard webhook or per-request signed webhook.
Can I use BladePDF without Laravel?
Yes, through the REST API. The bladepdf/laravel package is recommended for Laravel apps because it handles Blade rendering, local asset discovery, request construction, and typed responses.

Turn one existing Blade view into a production PDF.

Start synchronously, then add storage or async delivery only when the workflow needs it.

$ composer require bladepdf/laravel