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

Browsershot Laravel Package

spatie/browsershot

Convert web pages or HTML to images and PDFs using headless Chrome via Puppeteer. Capture screenshots, generate PDFs, render JS, extract body HTML, and inspect network requests. Simple fluent API for URLs, raw HTML, or local HTML files.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require spatie/browsershot
    npm install puppeteer
    

    Ensure puppeteer is installed globally or locally in your project.

  2. Basic Usage:

    use Spatie\Browsershot\Browsershot;
    
    // Save URL as image
    Browsershot::url('https://example.com')->save('screenshot.png');
    
    // Save URL as PDF
    Browsershot::url('https://example.com')->save('document.pdf');
    
    // Use HTML string
    Browsershot::html('<h1>Hello</h1>')->save('html_output.pdf');
    
  3. First Use Case: Generate a PDF of a dynamic dashboard for email reports:

    $dashboardUrl = route('admin.dashboard');
    Browsershot::url($dashboardUrl)
        ->setOption('format', 'A4')
        ->setOption('margin', '1cm')
        ->save(storage_path("app/reports/dashboard_{$date}.pdf"));
    

Where to Look First

  • Official Documentation: Covers all methods, options, and advanced use cases.
  • Browsershot class: Core class with chainable methods for configuration.
  • Puppeteer API: Underlying capabilities (e.g., evaluate(), waitForSelector()).

Implementation Patterns

Common Workflows

1. Dynamic Content Capture

  • Use Case: Rendering SPAs (React/Vue) or JavaScript-heavy pages.
  • Pattern:
    Browsershot::url('https://app.example.com/dashboard')
        ->waitForSelector('#dashboard-data') // Wait for JS to populate
        ->setOption('waitUntil', 'networkidle0')
        ->save('dashboard.png');
    

2. PDF Generation with Custom Styling

  • Use Case: Generating print-ready PDFs (e.g., invoices, certificates).
  • Pattern:
    Browsershot::html($invoiceHtml)
        ->setOption('printBackground', true)
        ->setOption('format', 'Letter')
        ->setOption('margin', '0.5in')
        ->setOption('landscape', true)
        ->save(storage_path("invoices/{$invoiceId}.pdf"));
    

3. Headless Chrome Configuration

  • Use Case: Optimizing performance or debugging.
  • Pattern:
    Browsershot::url('https://example.com')
        ->newHeadless() // Use Chrome's new headless mode
        ->setNodeBinaryPath('/usr/local/bin/node') // Custom Node path
        ->setOption('args', ['--no-sandbox', '--disable-setuid-sandbox'])
        ->save('output.pdf');
    

4. Interacting with Pages

  • Use Case: Simulating user actions (e.g., filling forms, clicking buttons).
  • Pattern:
    Browsershot::url('https://example.com/login')
        ->evaluate('document.querySelector("#email").value = "user@example.com"')
        ->evaluate('document.querySelector("#password").value = "password123"')
        ->click('#submit-button')
        ->waitForNavigation()
        ->save('login_success.png');
    

5. Batch Processing

  • Use Case: Generating thumbnails for a list of URLs.
  • Pattern:
    $urls = ['https://example.com/page1', 'https://example.com/page2'];
    foreach ($urls as $url) {
        $filename = str_replace(['https://', '/'], ['', '_'], $url) . '.png';
        Browsershot::url($url)->save(public_path("thumbnails/{$filename}"));
    }
    

6. Extracting Data

  • Use Case: Scraping rendered HTML or triggered requests.
  • Pattern:
    $html = Browsershot::url('https://example.com')->bodyHtml();
    $requests = Browsershot::url('https://example.com')->triggeredRequests();
    

Integration Tips

  • Queue Jobs: Offload heavy conversions to queues (e.g., Laravel Queues):
    Browsershot::dispatch($url, $path)->delay(now()->addMinutes(5));
    
  • Storage: Use Laravel Filesystem to handle paths:
    $path = storage_path("exports/{$filename}.pdf");
    Browsershot::url($url)->save($path);
    
  • Testing: Mock Browsershot in unit tests:
    $this->partialMock(Browsershot::class, 'url')->shouldReceive('save');
    

Gotchas and Tips

Pitfalls

  1. Puppeteer Dependencies:

    • Issue: Missing puppeteer or Chrome binary.
    • Fix: Run npm install puppeteer and ensure Chrome is installed.
    • Debug: Check logs for errors like Failed to launch chrome!.
  2. Timeouts:

    • Issue: Pages timing out due to slow JavaScript.
    • Fix: Adjust waitUntil or timeout:
      ->setOption('waitUntil', 'domcontentloaded') // Faster but less reliable
      ->setOption('timeout', 30000) // 30 seconds
      
  3. Localhost/Dev Server:

    • Issue: Browsershot blocking local URLs (e.g., Vite/HMR).
    • Fix: Use ->allowInsecureProtocol() or configure trustedProtocols:
      ->setOption('trustedProtocols', ['http:', 'https:', 'file:'])
      
  4. Memory Limits:

    • Issue: Large pages crashing Puppeteer.
    • Fix: Use chrome-headless-shell (legacy mode) or limit resources:
      ->setOption('args', ['--single-process', '--disable-gpu'])
      
  5. PDF Generation Quirks:

    • Issue: Incorrect margins or formatting.
    • Fix: Use CSS @page rules or Puppeteer’s pdf options:
      ->setOption('printBackground', true)
      ->setOption('margin', { top: '1cm', right: '1cm', bottom: '1cm', left: '1cm' })
      
  6. Sandboxing:

    • Issue: --no-sandbox errors in Docker/Linux.
    • Fix: Add to setOption('args') or configure Docker to allow sandboxing.

Debugging Tips

  • Logs: Enable verbose logging:
    ->setOption('logLevel', 'debug')
    
  • Inspect Pages: Use bodyHtml() to debug rendered output:
    $html = Browsershot::url($url)->bodyHtml();
    file_put_contents('debug.html', $html);
    
  • Puppeteer DevTools: Attach a debugger:
    ->setOption('devtools', true) // Opens DevTools (for local testing)
    

Extension Points

  1. Custom Puppeteer Scripts:

    • Inject JavaScript via evaluate() or evaluateOnNewDocument() (v5.4.0+):
      ->evaluateOnNewDocument('document.body.style.fontSize = "12pt"')
      
  2. Event Listeners:

    • Hook into Puppeteer events (e.g., request):
      Browsershot::url($url)
          ->on('request', function ($request) {
              logger()->debug($request->url());
          })
          ->save('output.pdf');
      
  3. Service Provider:

    • Bind a custom Browsershot instance for app-wide configuration:
      $this->app->singleton(Browsershot::class, function () {
          return new Browsershot(
              new Puppeteer([
                  'args' => ['--disable-setuid-sandbox'],
                  'timeout' => 60000,
              ])
          );
      });
      
  4. Fallbacks:

    • Handle failures gracefully:
      try {
          Browsershot::url($url)->save($path);
      } catch (\Exception $e) {
          Log::error("Browsershot failed: {$e->getMessage()}");
          // Fallback to static HTML or cached image
      }
      

Configuration Quirks

  • Node/NPM Paths:
    • Specify custom paths if puppeteer isn’t in PATH:
      ->setNodeBinaryPath('/custom/node')
      ->setNpmBinaryPath('/custom/npm')
      
  • Environment Variables:
    • Pass Node env vars (e.g., for auth tokens):
      ->setOption('env', ['API_TOKEN' => env('PUPPETEER
      
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.
codraw/entity-migrator
codraw/doctrine-extra
codraw/aws-tool-kit
codraw/validator
codraw/workflow
codraw/open-api
codraw/cron-job
codraw/process
codraw/log
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