Screenshot: Capture Images &amp; PDFs in Laravel | Mohamed Said       [Skip to content](#main)  [ ![](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MH.png) Mohamed SaidLaravel Backend Engineer ](https://www.msaied.com) - [Home](https://www.msaied.com)
- [Projects](https://www.msaied.com/projects)
- [Articles](https://www.msaied.com/articles)
- [Certificates](https://www.msaied.com/certificates)
- [About](https://www.msaied.com#about)

           [  Contact](https://www.msaied.com#contact) Menu 

Menu
----

Close 

 - [HomeStart here](https://www.msaied.com)
- [ProjectsCase studies](https://www.msaied.com/projects)
- [ArticlesEngineering notes](https://www.msaied.com/articles)
- [CertificatesCredentials](https://www.msaied.com/certificates)
- [AboutHow I work](https://www.msaied.com#about)
- [ContactGet in touch](https://www.msaied.com#contact)

  [Start a conversation](https://www.msaied.com#contact) [WhatsApp](https://wa.me/201094619204) [Email](mailto:hello@msaied.com) 

 1. [Home](https://www.msaied.com)
2. /
3. [Articles](https://www.msaied.com/articles)
4. /
5. [Laravel](https://www.msaied.com/articles?category=laravel)
6. /
7. Screenshot: Capture Images and PDFs from Blade Views and URLs in Laravel

   [Laravel](https://www.msaied.com/articles?category=laravel) [Composer Pacakge](https://www.msaied.com/articles?category=composer-pacakge) 

 Screenshot: Capture Images and PDFs from Blade Views and URLs in Laravel
=========================================================================

 The Screenshot package by Steve Bauman lets you capture Blade views, raw HTML, and public URLs as PNG, JPEG, or PDF files — all from PHP, with no Node.js or Puppeteer required.

 ![](https://cdn.msaied.com/01M22N44A70A5MC2S599JP0MPH.webp) [Mohamed Said](https://www.msaied.com#person) Published 21 Oct 2026 · Updated 23 Oct 2026 · 4 min read

ShareCopy linkCopied

 ![Screenshot: Capture Images and PDFs from Blade Views and URLs in Laravel](https://cdn.msaied.com/802/4b381a7cf7b496975aa9775d2454494f.png) 

  On this page +1. [Capture Images and PDFs with the Screenshot Package for Laravel](#capture-images-and-pdfs-with-the-screenshot-package-for-laravel)
2. [Capturing Views and URLs](#capturing-views-and-urls)
3. [Element Captures and PDFs](#element-captures-and-pdfs)
4. [Saving and Reusing a Capture](#saving-and-reusing-a-capture)
5. [Installation](#installation)

 Capture Images and PDFs with the Screenshot Package for Laravel
---------------------------------------------------------------

The [Screenshot package](https://github.com/DirectoryTree/Screenshot) by Steve Bauman gives Laravel applications a fluent PHP API for capturing Blade views, raw HTML, and live web pages as PNG, JPEG, or PDF files. Its default driver launches and controls Chrome directly from PHP — no Node.js, no Puppeteer. Captures can be saved to local storage or pushed to any Laravel filesystem disk.

Capturing Views and URLs
------------------------

Pass your content to `html()`, `view()`, or `url()` and chain format and size options. The example below generates a JPEG preview of a course completion certificate and stores it on S3:

```php
use DirectoryTree\Screenshot\Facades\Screenshot;

Screenshot::view('certificates.show', data: ['certificate' => $certificate])
    ->size(width: 1440, height: 900)
    ->jpeg(quality: 85)
    ->store(path: "certificates/{$certificate->id}/preview.jpg", disk: 's3');

```

PNG is the default format. Use `jpeg()` or `pdf()` explicitly — changing only the filename extension has no effect.

JavaScript is disabled by default. Enable it with `javascript()` when capturing a page that renders content client-side. The `viewport()` method restricts the capture to the visible viewport instead of the full page:

```php
Screenshot::url($product->public_url)
    ->javascript()
    ->size(width: 1280, height: 720)
    ->png()
    ->viewport()
    ->save(storage_path("app/product-{$product->id}-page.png"));

```

Screenshot waits for the page's `load` event. Pages that fetch data or render charts after that event may not be fully rendered when the capture fires. For Blade views, use absolute asset URLs or a `` tag so Chrome can resolve stylesheets and images.

Element Captures and PDFs
-------------------------

Call `element()` with a CSS selector to crop the capture to a specific DOM node. You can reuse the same source object to produce both a PNG and a PDF in one pass:

```php
use DirectoryTree\Screenshot\Enums\PaperSize;
use DirectoryTree\Screenshot\Facades\Screenshot;

$source = Screenshot::view('certificates.show', ['certificate' => $certificate])
    ->size(1440, 900)
    ->element('#certificate');

$source->png()->store(path: "certificates/{$certificate->id}/certificate.png", disk: 's3');

$source->pdf()
    ->paper(PaperSize::A4)
    ->landscape()
    ->store(path: "certificates/{$certificate->id}/certificate.pdf", disk: 's3');

```

For PDFs, Chrome moves the selected element into the document body and prints it with the document's stylesheets. CSS selectors that rely on removed wrapper elements may need adjustment. PDFs default to A4 portrait with 10 mm margins. Use `preferCssPageSize()` if your stylesheet defines an `@page` size.

Saving and Reusing a Capture
----------------------------

Calling `save()` or `store()` directly on a source triggers a new Chrome capture each time. To write the same capture to multiple destinations, call `capture()` first and reuse the result:

```php
$image = Screenshot::view('certificates.show', ['certificate' => $certificate])
    ->size(1440, 900)
    ->element('#certificate')
    ->png()
    ->capture();

$image->save(storage_path("app/certificate-{$certificate->id}.png"));
$image->store(
    path: "certificates/{$certificate->id}/certificate.png",
    disk: 's3',
    options: ['visibility' => 'private'],
);

```

The result object holds the captured bytes in memory, so both writes above use the same image without launching Chrome twice. Result objects also expose raw contents, Base64 data, and data URIs.

Installation
------------

```bash
composer require directorytree/screenshot
php artisan screenshot:install

```

The install command downloads Chrome for Testing automatically. Run with `--update` to fetch a newer stable version. To use an existing Chrome or Chromium binary, set `SCREENSHOT_CHROME_PATH`. The package also supports Gotenberg 8.38+ as a remote rendering driver.

In tests, `Screenshot::fake()` records captures without starting Chrome. Pair it with `Storage::fake()` when testing file uploads.

**Key takeaways:**

- Captures Blade views, raw HTML, and URLs as PNG, JPEG, or PDF — no Node.js required.
- `element()` crops captures to a CSS selector; useful for isolating a certificate or chart.
- `capture()` holds bytes in memory so you can write to multiple destinations in one Chrome session.
- JavaScript rendering is opt-in via `javascript()`; the package waits for the `load` event.
- Supports Laravel 12 (PHP 8.2+) and Laravel 13 (PHP 8.3+), with Gotenberg as an alternative driver.
- `Screenshot::fake()` makes the package fully testable without a real browser.

---

*Source: [Screenshot: Capture Images and PDFs with PHP and Laravel — Laravel News](https://laravel-news.com/screenshot)*

- [Laravel](https://www.msaied.com/articles?search=Laravel)
- [PHP](https://www.msaied.com/articles?search=PHP)
- [Screenshot](https://www.msaied.com/articles?search=Screenshot)
- [PDF](https://www.msaied.com/articles?search=PDF)
- [Headless Chrome](https://www.msaied.com/articles?search=Headless%20Chrome)
- [Packages](https://www.msaied.com/articles?search=Packages)

 Frequently asked questions 
---------------------------

  Does the Screenshot package require Node.js or Puppeteer?No. Its default driver launches and controls Chrome directly from PHP, so Node.js and Puppeteer are not required.

   How do I capture the same view as both a PNG and a PDF without running Chrome twice?Call `capture()` on the format chain to get a result object that holds the captured bytes in memory, then call `save()` or `store()` on that object as many times as needed. Calling `save()` or `store()` directly on the source starts a new capture each time.

   How can I test screenshot functionality without launching a real browser?Use `Screenshot::fake()` in your tests. It records captures without starting Chrome. Pair it with `Storage::fake()` when you also need to assert that files were stored.

   ![Mohamed Said](https://cdn.msaied.com/01M22N44A70A5MC2S599JP0MPH.webp)About the author
----------------

[Mohamed Said](https://www.msaied.com#person)Senior Backend Engineer specializing in Laravel, scalable SaaS platforms, APIs, and cloud infrastructure. I build secure, high-performance web applications that help businesses grow.

[About](https://www.msaied.com#about) [GitHub ↗](https://github.com/EG-Mohamed) [LinkedIn ↗](https://www.linkedin.com/in/msaiedm/) [WhatsApp ↗](https://wa.me/201094619204) [Email Address ↗](mailto:hello@msaied.com) [My CV ↗](https://drive.google.com/file/u/0/d/1MF20IPRJyzfy32mhEutjL5EpSls0w2Q8/view)  

   [Previous articleFilament v5.10.3 Released: Bug Fixes, Performance Improvements &amp; i18n Updates](https://www.msaied.com/articles/filament-v5103-released-bug-fixes-performance-improvements-i18n-updates)  

   On this page
-------------

1. [Capture Images and PDFs with the Screenshot Package for Laravel](#capture-images-and-pdfs-with-the-screenshot-package-for-laravel)
2. [Capturing Views and URLs](#capturing-views-and-urls)
3. [Element Captures and PDFs](#element-captures-and-pdfs)
4. [Saving and Reusing a Capture](#saving-and-reusing-a-capture)
5. [Installation](#installation)

 ###  Have a technical challenge?

 Tell me what you’re building. I reply within two working days.

[Start a conversation](https://www.msaied.com#contact) 

   Related articles
-----------------

 [ ![](https://cdn.msaied.com/800/c7c4a69453f0653a60c996daa58b2096.png) Laravel · 4 min read### Filament v5.10.3 Released: Bug Fixes, Performance Improvements &amp; i18n Updates

20 Oct 2026 ](https://www.msaied.com/articles/filament-v5103-released-bug-fixes-performance-improvements-i18n-updates) [ ![](https://cdn.msaied.com/801/da371310d5555269173fd04af50fde4b.png) Laravel · 4 min read### Filament v4.15.3 Released: Bug Fixes, Performance Improvements &amp; i18n Updates

20 Oct 2026 ](https://www.msaied.com/articles/filament-v4153-released-bug-fixes-performance-improvements-i18n-updates) [ ![](https://cdn.msaied.com/799/f5bb5eaa2b223303a224d6094f2b562c.png)  · 3 min read### Modular Monolith in Laravel: Enforcing Bounded Contexts Without a Microservices Tax

20 Oct 2026 ](https://www.msaied.com/articles/modular-monolith-in-laravel-enforcing-bounded-contexts-without-a-microservices-tax-4) 

  Have a technical challenge?
----------------------------

Tell me what you’re building. I reply within two working days.

 [Discuss your project ↗](https://www.msaied.com#contact) 

  © 2026 Mohamed Said · Built with Laravel, meant to last.Senior Backend Engineer specializing in Laravel, scalable SaaS platforms, APIs, and cloud infrastructure. I build secure, high-performance web applications that help businesses grow.

 - [Home](https://www.msaied.com)
- [Articles](https://www.msaied.com/articles)
- [Certificates](https://www.msaied.com/certificates)
- [GitHub](https://github.com/EG-Mohamed)
- [LinkedIn](https://www.linkedin.com/in/msaiedm/)
- [WhatsApp](https://wa.me/201094619204)
- [Email Address](mailto:hello@msaied.com)
- [My CV](https://drive.google.com/file/u/0/d/1MF20IPRJyzfy32mhEutjL5EpSls0w2Q8/view)
- [Sitemap](https://www.msaied.com/sitemap.xml)
