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 raw HTML to images and PDFs in PHP using Puppeteer-driven headless Chrome. Capture screenshots, generate PDFs, fetch rendered body HTML, and inspect triggered network requests—ideal for reports, previews, and testing.

View on GitHub
Deep Wiki
Context7
## Getting Started

### Minimal Steps
1. **Installation**:
   ```bash
   composer require spatie/browsershot
   npm install puppeteer  # or globally with `--global`

Ensure Node.js 22.0+ and Puppeteer are installed (see requirements).

  1. First Use Case: Capture a URL as an image:

    use Spatie\Browsershot\Browsershot;
    Browsershot::url('https://example.com')->save('screenshot.png');
    

    Capture a URL as a PDF:

    Browsershot::url('https://example.com')->save('document.pdf');
    
  2. Where to Look First:


Implementation Patterns

Core Workflows

  1. Dynamic Content Capture: Use bodyHtml() to fetch rendered HTML (post-JS execution):

    $html = Browsershot::url('https://example.com')->bodyHtml();
    
  2. Form Interaction: Simulate user actions before capture:

    Browsershot::url('https://example.com/login')
        ->type('#email', 'user@example.com')
        ->type('#password', 'password123')
        ->click('#submit')
        ->save('login_success.png');
    
  3. PDF Generation with Custom Styling: Emulate print media for cleaner PDFs:

    Browsershot::url('https://example.com/report')
        ->emulateMedia('print')
        ->save('report.pdf');
    
  4. Local HTML Processing: Render HTML from a file or string:

    // From file
    Browsershot::htmlFromFilePath('/path/to/template.html')
        ->setContentUrl('https://example.com') // Resolve relative assets
        ->save('template.png');
    
    // From string
    Browsershot::html('<h1>Hello</h1>')->save('string_output.pdf');
    
  5. New: Script Injection with evaluateOnNewDocument Execute scripts before the page loads (e.g., modify global state, inject CSS):

    Browsershot::url('https://example.com')
        ->evaluateOnNewDocument('document.title = "Custom Title"')
        ->save('modified_page.png');
    
    // Multiple scripts
    Browsershot::url('https://example.com')
        ->evaluateOnNewDocument([
            'document.body.style.backgroundColor = "lightblue"',
            'window.customVar = "injected"',
        ])
        ->save('styled_page.pdf');
    

Integration Tips

  • Queue Jobs for Async Processing: Use Laravel queues to avoid blocking requests:

    Browsershot::url('https://example.com')->save('async.png')->onQueue('browsershot');
    
  • Store Outputs in Storage: Save files to Laravel’s filesystem:

    use Illuminate\Support\Facades\Storage;
    Browsershot::url('https://example.com')->save(Storage::path('screenshots/example.png'));
    
  • Debugging with Redirects: Log redirect history to diagnose issues:

    $redirects = Browsershot::url('https://example.com')->redirectHistory();
    foreach ($redirects as $redirect) {
        logger()->info('Redirect:', ['url' => $redirect['url'], 'status' => $redirect['status']]);
    }
    
  • Custom Headers for APIs: Authenticate or modify requests:

    Browsershot::url('https://api.example.com/protected')
        ->setExtraHttpHeaders(['Authorization' => 'Bearer token123'])
        ->save('api_screenshot.png');
    
  • Combine evaluateOnNewDocument with Other Features: Use it alongside delay() or emulateMedia() for complex workflows:

    Browsershot::url('https://example.com/dashboard')
        ->evaluateOnNewDocument('localStorage.setItem("theme", "dark")')
        ->emulateMedia('print')
        ->delay(1500)
        ->save('dashboard_print.pdf');
    

Gotchas and Tips

Pitfalls

  1. Missing Dependencies:

    • Symptom: PuppeteerException or blank outputs.
    • Fix: Ensure Node.js, Puppeteer, and system libraries (e.g., libx11-xcb1 on Linux) are installed. For Forge servers, follow the custom setup guide.
  2. Resource Leaks:

    • Symptom: High memory usage or crashes when processing many pages.
    • Fix: Disable URL capture for data-heavy pages:
      Browsershot::html('<div>...</div>')->disableCaptureURLs();
      
  3. Stale or Incorrect Outputs:

    • Symptom: Screenshots/PDFs don’t match the live page.
    • Debug:
      • Check redirectHistory() for unexpected redirects.
      • Verify emulateMedia() settings (e.g., print vs. screen).
      • Add delays for dynamic content:
        Browsershot::url('https://example.com')->delay(2000)->save('page.png');
        
    • New: If using evaluateOnNewDocument, ensure scripts run before the page loads. Test with console.log in scripts to verify execution order.
  4. Font Rendering Issues:

    • Symptom: Garbled text on Linux (e.g., CentOS).
    • Fix: Pass Chromium arguments:
      Browsershot::url('https://example.com')
          ->addChromiumArguments(['font-render-hinting' => 'none']);
      
  5. POST Requests:

    • Gotcha: Only application/x-www-form-urlencoded is supported.
    • Workaround: Pre-generate the form data on the server side.
  6. evaluateOnNewDocument Limitations:

    • Gotcha: Scripts run in an isolated context (no access to window or document until after page creation).
    • Workaround: Use evaluate() for post-load modifications:
      Browsershot::url('https://example.com')
          ->evaluateOnNewDocument('window.__INJECTED__ = true')
          ->evaluate('document.body.style.color = "red"')
          ->save('modified.png');
      

Debugging Tips

  • Log Puppeteer Output: Enable verbose logging via Chromium arguments:

    Browsershot::url('https://example.com')
        ->addChromiumArguments(['log-level' => 'debug']);
    
  • Inspect Triggered Requests: Debug API calls or resource loading:

    $requests = Browsershot::url('https://example.com')->triggeredRequests();
    dd($requests); // Inspect URLs, statuses, and headers.
    
  • Test evaluateOnNewDocument Scripts: Use console.log to verify script execution:

    Browsershot::url('https://example.com')
        ->evaluateOnNewDocument('console.log("Script ran!");')
        ->save('debug.png');
    

    Check Puppeteer logs for output.

  • Test Locally First: Use newHeadless() for debugging (slower but easier to attach Chrome DevTools):

    Browsershot::url('https://example.com')->newHeadless()->save('debug.png');
    

Extension Points

  1. Custom Puppeteer Scripts: Override the default script path:

    Browsershot::html('...')->setBinPath('/path/to/custom-script.js');
    
  2. Environment-Specific Config: Use Laravel’s config to centralize settings (e.g., config/browsershot.php):

    // In a service provider
    Browsershot::macro('configure', function () {
        $this->setChromePath(config('browsershot.chrome_path'));
        $this->addChromiumArguments(config('browsershot.chromium_args'));
    });
    
  3. Event Listeners: Extend functionality by tapping into Puppete

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.
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope
anil/file-picker
broqit/fields-ai