name: laravel-screenshot description: Take screenshots of web pages in Laravel using spatie/laravel-screenshot. Covers taking screenshots of URLs and HTML, customizing viewport and format, saving to disks, queued generation, testing, and configuring drivers (Browsershot, Cloudflare).
Laravel Screenshot
When to use this skill
Use this skill when the user needs to take screenshots of web pages in a Laravel application using spatie/laravel-screenshot. This includes taking screenshots of URLs or HTML, customizing viewport size and image format, saving to filesystem disks, queued screenshot generation, testing screenshots, and configuring drivers.
Taking screenshots
Screenshot a URL:
use Spatie\LaravelScreenshot\Facades\Screenshot;
Screenshot::url('https://example.com')->save('screenshot.png');
Screenshot raw HTML:
Screenshot::html('<h1>Hello world!</h1>')->save('hello.png');
Customizing screenshots
Viewport size
Screenshot::url('https://example.com')
->width(1920)->height(1080)
->save('screenshot.png');
// Or use size() as shorthand:
Screenshot::url('https://example.com')
->size(1920, 1080)
->save('screenshot.png');
Image format
The format is determined from the file extension: .png, .jpg/.jpeg, .webp.
Screenshot::url('https://example.com')->save('screenshot.jpg');
Screenshot::url('https://example.com')->save('screenshot.webp');
Image quality
For JPEG and WebP (0-100):
Screenshot::url('https://example.com')
->quality(80)
->save('screenshot.jpg');
Device scale factor
Default is 2x (retina):
Screenshot::url('https://example.com')
->deviceScaleFactor(1)
->save('screenshot.png');
Full page screenshots
Screenshot::url('https://example.com')
->fullPage()
->save('full-page.png');
Element screenshots
Screenshot::url('https://example.com')
->selector('.hero-section')
->save('hero.png');
Clip region
Screenshot::url('https://example.com')
->clip(0, 0, 800, 600)
->save('clipped.png');
Transparent background
Screenshot::url('https://example.com')
->selector('.logo')
->omitBackground()
->save('logo.png');
Wait strategies
// Wait for network idle
Screenshot::url('https://example.com')
->waitUntil('networkidle0')
->save('screenshot.png');
// Wait for a CSS selector
Screenshot::url('https://example.com')
->waitForSelector('.content-loaded')
->save('screenshot.png');
// Wait for a duration (ms)
Screenshot::url('https://example.com')
->waitForTimeout(3000)
->save('screenshot.png');
Conditional customization
Screenshot::url('https://example.com')
->when($needsFullPage, fn ($screenshot) => $screenshot->fullPage())
->save('screenshot.png');
Saving to disks
Screenshot::url('https://example.com')
->disk('s3')
->save('screenshots/homepage.png');
// With visibility:
Screenshot::url('https://example.com')
->disk('s3', 'public')
->save('screenshots/homepage.png');
Base64
$base64 = Screenshot::url('https://example.com')->base64();
Drivers
The package supports two drivers: browsershot (default) and cloudflare.
Set the driver via LARAVEL_SCREENSHOT_DRIVER env variable or in config/laravel-screenshot.php.
Browsershot driver
Requires spatie/browsershot installed separately:
composer require spatie/browsershot
Customize the Browsershot instance per screenshot:
use Spatie\Browsershot\Browsershot;
Screenshot::url('https://example.com')
->withBrowsershot(function (Browsershot $browsershot) {
$browsershot
->setExtraHttpHeaders(['Authorization' => 'Bearer token'])
->userAgent('My Custom User Agent');
})
->save('screenshot.png');
Cloudflare driver
Uses Cloudflare's Browser Rendering API. No Node.js or Chrome binary needed.
LARAVEL_SCREENSHOT_DRIVER=cloudflare
CLOUDFLARE_API_TOKEN=your-api-token
CLOUDFLARE_ACCOUNT_ID=your-account-id
The Cloudflare driver does not support withBrowsershot().
Switch driver per screenshot:
Screenshot::url('https://example.com')
->driver('cloudflare')
->save('screenshot.png');
Queued screenshot generation
Dispatch screenshot generation to a background queue:
Screenshot::url('https://example.com')
->saveQueued('screenshot.png')
->then(fn (string $path, ?string $diskName) => Mail::to($user)->send(new ScreenshotMail($path)))
->catch(fn (Throwable $e) => Log::error($e->getMessage()));
Configure queue and connection:
Screenshot::url('https://example.com')
->saveQueued('screenshot.png')
->onQueue('screenshots')
->onConnection('redis')
->delay(now()->addMinutes(5));
With disk:
Screenshot::url('https://example.com')
->disk('s3')
->saveQueued('screenshots/homepage.png');
Note: saveQueued() cannot be used with withBrowsershot().
Extending with macros
Register macros in a service provider:
use Spatie\LaravelScreenshot\ScreenshotBuilder;
ScreenshotBuilder::macro('mobile', function () {
return $this->size(375, 812)->deviceScaleFactor(3);
});
Then use them:
Screenshot::url('https://example.com')->mobile()->save('mobile.png');
Testing
Fake screenshot generation in tests:
use Spatie\LaravelScreenshot\Facades\Screenshot;
beforeEach(function () {
Screenshot::fake();
});
Assert a screenshot was saved:
Screenshot::assertSaved('screenshots/homepage.png');
Screenshot::assertSaved(function ($screenshot, string $path) {
return $path === 'screenshots/homepage.png'
&& $screenshot->url === 'https://example.com';
});
Assert URL or HTML:
Screenshot::assertUrlIs('https://example.com');
Screenshot::assertHtmlContains('Hello World');
Assert queued screenshots:
Screenshot::assertQueued('screenshots/homepage.png');
Screenshot::assertQueued(fn ($screenshot, string $path) => $path === 'screenshots/homepage.png');
Screenshot::assertNotQueued();