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

Render web pages (URLs or HTML) to images or PDFs from PHP/Laravel using headless Chrome via Puppeteer. Save screenshots/PDFs, render local HTML files, extract post-JS body HTML, and inspect requests triggered by a page.

View on GitHub
Deep Wiki
Context7

Getting Started

First, ensure Node.js (v22+), npm, and Puppeteer are installed globally (npm install puppeteer --location=global). Install the package via Composer: composer require spatie/browsershot. Then, start with the most basic use case: convert a URL to an image or PDF. For example:

use Spatie\Browsershot\Browsershot;

// Save as PNG/JPEG
Browsershot::url('https://example.com')->save('screenshot.png');

// Save as PDF (detection by .pdf extension)
Browsershot::url('https://example.com')->save('report.pdf');

// Render HTML string directly
Browsershot::html('<h1>Hello World</h1>')->save('card.pdf');

This covers common first steps—snapshotting live pages, generating PDFs from HTML fragments, or local files (using htmlFromFilePath). Check vendor/spatie/browsershot/README.md and official docs at spatie.be/docs/browsershot for full method reference.


Implementation Patterns

Dynamic Report Generation in Jobs: Dispatch a queued job that renders HTML templates (e.g., invoice, dashboard summary) to PDF or image. Inject Laravel view data, then use Browsershot’s html() method. Combine with Blade’s view('reports.invoice', $data)->render().

Test-Driven UI Validation: In feature tests, assert that dynamically rendered pages (e.g., dynamic pricing configurator) match expected layout by capturing and comparing images using image-diff tools (e.g., image-diff CLI).

Form Preview Generation: Allow users to preview submitted forms before saving. On form preview request, render the final HTML using html(), optionally simulate user input via type(), selectOption(), and click(), then generate image/PDF snapshot for confirmation.

Conditional Media Emulation: For responsive UI testing or print-preview, use emulateMedia('print') or emulateMediaFeatures() with prefers-color-scheme=dark. Crucial for accurate visual testing of CSS-driven themes.

Redirect & Request Auditing: When diagnosing inconsistent screenshots, inspect redirectHistory() and triggeredRequests()—especially for geo/localized redirects or A/B test endpoints that alter output.

Custom Environment for Localization: Use setEnvironmentOptions(['LANG' => 'fr-FR']) to render pages in correct locale (e.g., date formats, translated UI), even if server locale differs.

Performance Optimization: When using data URIs (e.g., SVG sprites), call disableCaptureURLs() to reduce memory footprint. Prevents Puppeteer from caching unused assets.


Gotchas and Tips

Font Rendering on Linux: Fonts may appear jagged on headless Linux servers (especially CentOS). Fix with addChromiumArguments(['font-render-hinting' => 'none']) or install fonts via apt install fonts-liberation.

Node Binary Discovery Failures: In isolated environments (e.g., Forge, Docker, shared hosts), explicitly set setNodeBinary() and setNpmBinary() or use setIncludePath() to extend $PATH. Verify with which node and which npm.

PDF Page Size & Margins: By default, PDFs use US Letter size. Adjust with margins() method: ->margins(10, 5, 10, 5) (top/right/bottom/left in mm). Use size('A4') or custom dimensions (->size(210, 297)).

Wait for JavaScript to Settle: Dynamic content may not be rendered synchronously. Use ->delay(500) after type()/click(), or consider ->waitForFunction('document.querySelector(".loaded")') for robustness.

POST Data Parsing: POST payload uses application/x-www-form-urlencoded. If expecting JSON, handle in middleware (client-side) or use html() instead to bypass navigation entirely.

HTML Base URL Trap: Relative assets (e.g., /img/logo.png) fail when using html() because Puppeteer lacks a base URL. Use setContentUrl('https://app.test') to ensure correct resolution.

Browser Version Mismatch: Puppeteer v23+ bundles a specific Chromium version. If chmod errors occur, explicitly install Chromium via npx puppeteer browsers install chrome. Avoid mixing global puppeteer versions.

Memory & Timeout Limits: Long pages or heavy JS may time out. Configure via ->timeout(60) (seconds) and avoid capturing full-page unnecessarily—use ->showBackground() only if needed for PDF backgrounds (adds ~2x memory).

Headless vs New Headless Mode: Use newHeadless() for modern Chrome headless (faster, more reliable) unless debugging—older headless: true may be needed for legacy Puppeteer setups. Prefer the former unless hitting --disable-gpu issues on VMs.

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