Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Snappy Laravel Package

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.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require barryvdh/laravel-snappy
    

    Publish the config:

    php artisan vendor:publish --provider="Barryvdh\Snappy\ServiceProvider"
    
  2. 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' => [],
    ],
    
  3. 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');
    

Where to Look First

  • Facade: Barryvdh\Snappy\Facades\SnappyPdf (primary entry point).
  • Configuration: config/snappy.php (adjust paths, options, and environment variables).
  • Queue Jobs: Barryvdh\Snappy\Jobs\SnappyPdfJob (for async generation).
  • Events: Barryvdh\Snappy\Events\Generating, Barryvdh\Snappy\Events\Generated (for custom logic).

Implementation Patterns

Core Workflows

1. Synchronous PDF Generation

  • From Blade View:
    return SnappyPdf::loadView('invoice', ['user' => $user])
        ->setOption('footer-center', '[page]/[topage]')
        ->download('invoice_'.$user->id.'.pdf');
    
  • From HTML String:
    $html = '<h1>Hello, PDF!</h1><p>Generated dynamically.</p>';
    return SnappyPdf::loadHtml($html)->stream();
    

2. Asynchronous PDF Generation

Use Laravel queues to offload heavy PDF generation:

use Barryvdh\Snappy\Jobs\SnappyPdfJob;

SnappyPdfJob::dispatch('pdf.template', ['data' => $data], 'document.pdf')
    ->onQueue('pdfs');
  • Handle Job Completion:
    public function handle(SnappyPdfJob $job) {
        $pdf = $job->pdf();
        Storage::disk('s3')->put('pdfs/'.$job->filename, $pdf->output());
    }
    

3. Dynamic Content Injection

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]']));

4. Custom Headers/Footers

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]));

5. Storing PDFs

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

Integration Tips

Laravel Mix/Vite Assets

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');

Localization

Generate multi-language PDFs using Laravel’s localization:

$pdf = SnappyPdf::loadView('document', ['locale' => 'es'])
    ->setOption('encoding', 'UTF-8');

Middleware for PDF Generation

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');
});

Testing

Use SnappyPdf in tests with mock views:

public function testPdfGeneration() {
    $pdf = SnappyPdf::loadView('test.pdf', ['data' => 'test']);
    $this->assertStringContainsString('test', $pdf->output());
}

Docker Setup

Use a pre-built image with wkhtmltopdf:

FROM barryvdh/laravel-snappy:latest
COPY . /var/www/html
WORKDIR /var/www/html

Gotchas and Tips

Pitfalls

1. wkhtmltopdf Path Issues

  • Symptom: Binary not found or Command not found errors.
  • Fix:
    • Ensure the binary is installed (sudo apt-get install wkhtmltopdf on Ubuntu).
    • Verify the path in config/snappy.php is correct (use absolute paths).
    • For Docker, mount the binary or use a pre-built image.

2. CSS Rendering Quirks

  • Symptom: Tables, headers/footers, or complex layouts render incorrectly.
  • Fix:
    • Avoid position: fixed, float, or complex Flexbox/Grid.
    • Use !important sparingly; Snappy may override styles.
    • Test with WkHTMLToPDF’s CSS support guide.
    • Example fix for headers/footers:
      $pdf->setOption('header-html', view('pdf.header'))
          ->setOption('header-spacing', '10');
      

3. Memory/Timeout Errors

  • Symptom: PDF generation fails with Timeout or Allowed memory exhausted.
  • Fix:
    • Increase PHP memory limit (memory_limit in php.ini).
    • Use queues for large PDFs:
      SnappyPdfJob::dispatch('large-report', $data)->delay(now()->addMinutes(5));
      
    • Optimize HTML/CSS (e.g., inline styles, minimal JS).

4. JavaScript Execution Limitations

  • Symptom: Dynamic content via JS doesn’t render.
  • Fix:
    • Avoid JS for critical content; use server-side logic instead.
    • If JS is required, enable it in config:
      'options' => ['enable-javascript' => true],
      
    • Note: This may introduce security risks (XSS).

5. Font Rendering Issues

  • Symptom: Custom fonts don’t appear in PDF.
  • Fix:
    • Ensure fonts are embedded in your HTML/CSS:
      @font-face {
          font-family: 'CustomFont';
          src: url('/fonts/CustomFont.woff2') format('woff2');
      }
      
    • Specify font in config:
      $pdf->setOption('encoding', 'UTF-8')
          ->setOption('font-size', '12');
      

6. Queue Job Failures

  • Symptom: SnappyPdfJob fails silently.
  • Fix:
    • Check job logs (php artisan queue:work --verbose).
    • Ensure the job has access to the same wkhtmltopdf binary as the web server.
    • Retry failed jobs:
      $job->retryAfter(5);
      

Debugging Tips

1. Log PDF Generation

Use events to log generation details:

SnappyPdf::setEventDispatcher($dispatcher);
$dispatcher->listen(Generating::class, function ($event) {
    Log::info('Generating PDF', ['options' => $event->pdf->getOptions()
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
ecotone/kafka
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata