barryvdh/laravel-snappy
Generate PDF and image files in Laravel using wkhtmltopdf/wkhtmltoimage. Provides simple facades and service provider setup, config options, and easy rendering from views or HTML strings with headers, footers, and custom binaries.
Installation:
composer require barryvdh/laravel-snappy
Publish the config:
php artisan vendor:publish --provider="Barryvdh\Snappy\ServiceProvider"
Configure wkhtmltopdf Path:
Edit config/snappy.php to specify the path to the wkhtmltopdf binary:
'pdf' => [
'enabled' => true,
'binary' => base_path('vendor/bin/wkhtmltopdf'), // or custom path
'timeout' => false,
'options' => [],
'env' => [],
],
First Use Case: Generate a PDF from a Blade view and stream it to the browser:
use Barryvdh\Snappy\Facades\SnappyPdf;
return SnappyPdf::loadView('pdf.template', ['data' => $data])
->setOption('margin-top', '20mm')
->setOption('margin-bottom', '20mm')
->stream('document.pdf');
Barryvdh\Snappy\Facades\SnappyPdf (primary entry point).config/snappy.php (adjust paths, options, and environment variables).Barryvdh\Snappy\Jobs\SnappyPdfJob (for async generation).Barryvdh\Snappy\Events\Generating, Barryvdh\Snappy\Events\Generated (for custom logic).return SnappyPdf::loadView('invoice', ['user' => $user])
->setOption('footer-center', '[page]/[topage]')
->download('invoice_'.$user->id.'.pdf');
$html = '<h1>Hello, PDF!</h1><p>Generated dynamically.</p>';
return SnappyPdf::loadHtml($html)->stream();
Use Laravel queues to offload heavy PDF generation:
use Barryvdh\Snappy\Jobs\SnappyPdfJob;
SnappyPdfJob::dispatch('pdf.template', ['data' => $data], 'document.pdf')
->onQueue('pdfs');
public function handle(SnappyPdfJob $job) {
$pdf = $job->pdf();
Storage::disk('s3')->put('pdfs/'.$job->filename, $pdf->output());
}
Pass data to Blade templates and use Snappy’s options for dynamic styling:
$pdf = SnappyPdf::loadView('report', ['metrics' => $metrics])
->setOption('header-html', view('pdf.header', ['logo' => $logo]))
->setOption('footer-html', view('pdf.footer', ['page' => '[page]']));
Use HTML/CSS for reusable headers/footers:
// In your Blade template (e.g., resources/views/pdf/header.blade.php)
<table style="width: 100%; border-collapse: collapse;">
<tr><td style="text-align: center;"><img src="{{ $logo }}" /></td></tr>
</table>
// In your controller
$pdf = SnappyPdf::loadView('document')
->setOption('header-html', view('pdf.header', ['logo' => $logo]));
Save PDFs to filesystem, S3, or database:
// Save to filesystem
$pdf->save(storage_path('app/pdf/document.pdf'));
// Save to S3
$pdf->saveToDisk('s3', 'pdfs/document.pdf');
// Save to database (as binary)
$pdf->saveAsBase64(); // Get base64 string, then store in DB
Include compiled assets (CSS/JS) in PDFs:
// In your Blade template
@vite(['resources/css/pdf.css', 'resources/js/pdf.js'])
// Ensure assets are accessible via absolute URLs
$pdf = SnappyPdf::loadView('document')
->setOption('base-url', 'https://your-app.com');
Generate multi-language PDFs using Laravel’s localization:
$pdf = SnappyPdf::loadView('document', ['locale' => 'es'])
->setOption('encoding', 'UTF-8');
Add logic before/after PDF generation:
SnappyPdf::setEventDispatcher($dispatcher);
// Listen for generating event
$dispatcher->listen(Generating::class, function ($event) {
$event->pdf->setOption('custom-header', 'Processed by Middleware');
});
Use SnappyPdf in tests with mock views:
public function testPdfGeneration() {
$pdf = SnappyPdf::loadView('test.pdf', ['data' => 'test']);
$this->assertStringContainsString('test', $pdf->output());
}
Use a pre-built image with wkhtmltopdf:
FROM barryvdh/laravel-snappy:latest
COPY . /var/www/html
WORKDIR /var/www/html
wkhtmltopdf Path IssuesBinary not found or Command not found errors.sudo apt-get install wkhtmltopdf on Ubuntu).config/snappy.php is correct (use absolute paths).position: fixed, float, or complex Flexbox/Grid.!important sparingly; Snappy may override styles.$pdf->setOption('header-html', view('pdf.header'))
->setOption('header-spacing', '10');
Timeout or Allowed memory exhausted.memory_limit in php.ini).SnappyPdfJob::dispatch('large-report', $data)->delay(now()->addMinutes(5));
'options' => ['enable-javascript' => true],
@font-face {
font-family: 'CustomFont';
src: url('/fonts/CustomFont.woff2') format('woff2');
}
$pdf->setOption('encoding', 'UTF-8')
->setOption('font-size', '12');
SnappyPdfJob fails silently.php artisan queue:work --verbose).wkhtmltopdf binary as the web server.$job->retryAfter(5);
Use events to log generation details:
SnappyPdf::setEventDispatcher($dispatcher);
$dispatcher->listen(Generating::class, function ($event) {
Log::info('Generating PDF', ['options' => $event->pdf->getOptions()
How can I help you explore Laravel packages today?