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

Laravel wrapper for wkhtmltopdf and wkhtmltoimage, enabling fast HTML-to-PDF and HTML-to-image generation. Supports headers/footers, page options, and easy integration with views, files, and responses for downloads or storage.

View on GitHub
Deep Wiki
Context7
## Getting Started

### Minimal Steps
1. **Installation**:
   ```bash
   composer require barryvdh/laravel-snappy
   php artisan vendor:publish --provider="Barryvdh\Snappy\SnappyServiceProvider" --tag="snappy-config"

Update config/snappy.php with the correct binary paths for your OS (e.g., /usr/local/bin/wkhtmltopdf for Linux/Mac or C:\Program Files\wkhtmltopdf\bin\wkhtmltopdf.exe for Windows).

  1. Verify Binary Installation:

    • Linux/Mac: Install via package manager (sudo apt-get install wkhtmltopdf or brew install wkhtmltopdf).
    • Windows: Download from wkhtmltopdf.org and add to PATH.
    • Docker: Use the wkhtmltopdf/wkhtmltopdf image or install in your container.
  2. First Use Case (PDF from Blade View):

    use Barryvdh\Snappy\Facades\SnappyPdf;
    
    public function generatePdf() {
        return SnappyPdf::loadView('pdf.template', ['data' => $this->data])
            ->setOption('margin-top', '20mm')
            ->download('document.pdf');
    }
    

    Create a Blade template at resources/views/pdf/template.blade.php.


Implementation Patterns

Core Workflows

1. PDF Generation

  • From Blade View:

    SnappyPdf::loadView('invoices.pdf', ['invoice' => $invoice])
        ->setOption('page-size', 'A4')
        ->setOption('orientation', 'Portrait')
        ->stream('invoice.pdf');
    
  • From Raw HTML String:

    $html = '<h1>Custom Report</h1><table>' . $tableData . '</table>';
    SnappyPdf::loadHtml($html)
        ->setOption('encoding', 'UTF-8')
        ->save(storage_path("reports/custom.pdf"));
    
  • From URL:

    SnappyPdf::loadUrl('https://example.com/report')
        ->setOption('allow', 'example.com')
        ->save(storage_path("reports/external.pdf"));
    

2. Image Generation

  • From Blade View:
    use Barryvdh\Snappy\Facades\SnappyImage;
    
    SnappyImage::loadView('dashboard.preview', $data)
        ->setOption('width', 800)
        ->setOption('height', 600)
        ->download('dashboard_preview.png');
    

3. Queued Jobs

  • Job Implementation:
    public function handle($data) {
        $pdf = SnappyPdf::loadView('reports.detailed', $data)
            ->setOption('lowquality')
            ->getContent();
    
        Storage::disk('s3')->put("reports/{$data['id']}.pdf", $pdf);
    }
    
  • Dispatch Job:
    GenerateReportJob::dispatch($data)->onQueue('pdfs');
    

4. Dynamic Headers and Footers

  • Static Headers/Footers:
    SnappyPdf::loadView('document')
        ->setOption('header-html', 'file://' . resource_path('views/partials/header.blade.php'))
        ->setOption('footer-html', 'file://' . resource_path('views/partials/footer.blade.php'))
        ->download('document.pdf');
    

5. Streaming and Downloading

  • Stream PDF:

    return SnappyPdf::loadView('document', $data)
        ->stream('document.pdf', [
            'Content-Disposition' => 'inline; filename="document.pdf"',
        ]);
    
  • Force Download:

    return SnappyPdf::loadView('document', $data)
        ->download('document.pdf');
    

6. Caching Generated PDFs

  • Cache PDF Content:
    $pdf = Cache::remember("pdf_{$id}", now()->addHours(1), function () use ($id) {
        return SnappyPdf::loadView('template', ['id' => $id])->getContent();
    });
    return response($pdf, 200)->header('Content-Type', 'application/pdf');
    

Configuration

  • Global Options in config/snappy.php:

    'pdf' => [
        'binary' => env('WKHTMLTOPDF_BINARY', '/usr/local/bin/wkhtmltopdf'),
        'options' => [
            'margin-top' => '15mm',
            'encoding' => 'UTF-8',
            'no-outline',
        ],
    ],
    
  • Environment-Specific Overrides:

    WKHTMLTOPDF_BINARY=/custom/path/wkhtmltopdf
    WKHTMLTOIMAGE_BINARY=/custom/path/wkhtmltoimage
    

Integration with Laravel Features

  • API Responses:

    return SnappyPdf::loadView('view', $data)
        ->stream('document.pdf', [
            'Content-Disposition' => 'attachment; filename="document.pdf"',
        ]);
    
  • Mail Attachments:

    $pdf = SnappyPdf::loadView('email.template', $data)->getContent();
    Mail::send([], [], function ($message) use ($pdf) {
        $message->attachData($pdf, 'document.pdf', ['mime' => 'application/pdf']);
    });
    
  • Storage Integration:

    $pdf = SnappyPdf::loadView('view')->getContent();
    Storage::disk('s3')->put("reports/{$id}.pdf", $pdf);
    

Gotchas and Tips

Pitfalls

  1. Binary Path Issues:

    • Symptom: Binary not found or blank PDFs.
    • Fix: Verify paths in config/snappy.php and ensure binaries are in PATH or use absolute paths.
    • Debug:
      which wkhtmltopdf  # Linux/Mac
      where wkhtmltopdf  # Windows
      
  2. CSS/Font Rendering Problems:

    • Symptom: Missing fonts or incorrect styling.
    • Fix:
      • Use absolute paths for fonts (e.g., src: url('/fonts/Roboto.ttf')).
      • Avoid @font-face in Blade; embed fonts directly.
      • Test with --debug-js to identify rendering issues.
  3. Complex Layouts:

    • Symptom: position: fixed or overflow: hidden elements may not render.
    • Fix: Simplify CSS or use setOption('enable-internal-links').
  4. Memory Limits:

    • Symptom: Allowed memory exhausted for large PDFs.
    • Fix:
      • Increase memory_limit in php.ini.
      • Use setOption('lowquality') for drafts.
      • Process in chunks or use queued jobs.
  5. Queue Failures:

    • Symptom: Jobs fail silently in production.
    • Fix:
      • Ensure wkhtmltopdf is installed in all environments.
      • Log job failures:
        try {
            // Generate PDF
        } catch (\Exception $e) {
            Log::error("PDF generation failed: " . $e->getMessage());
            throw $e;
        }
        
  6. Headers/Footers Not Rendering:

    • Symptom: Custom headers/footers appear blank.
    • Fix:
      • Use absolute paths for header/footer HTML files.
      • Ensure HTML is valid and self-contained.

Debugging

  • Enable Debugging Options:

    SnappyPdf::loadView('view')
        ->setOption('debug-js')
        ->setOption('enable-js')
        ->save('debug.pdf');
    
  • Test Binary Directly:

    wkhtmltopdf --version
    wkhtmltopdf input.html output.pdf
    
  • Check Logs:

    SnappyPdf::loadView('view')
        ->setOption('quiet')
        ->save('output.pdf');
    

Tips

  1. Dynamic Options:

    $options = [
        'margin-top' => '25mm',
        'margin-right' => '20mm',
        'margin-bottom' => '25mm',
        'margin-left' => '20mm',
        'header-center' => 'My Company',
        'footer-center' => '[page]/[topage]',
    ];
    SnappyPdf::loadView('view')->setOptions($options)->download('document.pdf');
    
  2. Use Facades for Cleaner Code:

    // Instead of:
    $pdf = app('snappy.pdf')->loadView('view')->getContent();
    
    // Use:
    $pdf = SnappyPdf::loadView('view')->getContent();
    
  3. **Leverage Laravel Mix for CSS/

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.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport