PHPackages                             visualbuilder/filament-screenshot-catalogue - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. visualbuilder/filament-screenshot-catalogue

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

visualbuilder/filament-screenshot-catalogue
===========================================

Capture every page of a Filament v5 panel at multiple viewports and modes, upload to S3, generate a browsable index. Drop-in tooling for visual QA, design reviews, marketing assets, and AI-driven visual regression.

5.7.0(3w ago)5600—7.9%1GPL-2.0-or-laterPHPPHP ^8.2

Since May 2Pushed 3w agoCompare

[ Source](https://github.com/visualbuilder/filament-screenshot-catalogue)[ Packagist](https://packagist.org/packages/visualbuilder/filament-screenshot-catalogue)[ Docs](https://github.com/visualbuilder/filament-screenshot-catalogue)[ RSS](/packages/visualbuilder-filament-screenshot-catalogue/feed)WikiDiscussions 5.x Synced 1w ago

READMEChangelogDependencies (11)Versions (18)Used By (1)

Filament Panel Screenshot Catalogue
===================================

[](#filament-panel-screenshot-catalogue)

Capture every page of a Filament v5 panel — at desktop, tablet, and mobile breakpoints, in light and dark mode — upload to S3, and publish a browsable, link-shareable index. Designed as the data source for visual QA, design reviews, marketing assets, and AI-driven visual regression workflows.

What you get
------------

[](#what-you-get)

```
php artisan panel:sitemap --panel=admin                  # discover every URL
php artisan screenshot:dispatch --panel=admin --tag=latest   # queue per-page capture jobs
php artisan screenshot:capture --panel=admin --page=dashboard --tag=latest   # one-off sync run
php artisan screenshot:rebuild-index --panel=admin --tag=latest   # rebuild index.html only
```

The pipeline is:

1. **Sitemap generator** walks the panel's resources, custom pages and auth screens, picks a representative record for `view`/`edit` URLs, and saves a JSON manifest to `storage/app/sitemap-{panel}.json`.
2. **Capture jobs** drive Playwright through every entry × every viewport × every mode, save PNGs locally, and upload to your configured S3 disk.
3. **Index builder** lists the run's S3 prefix and renders `index.html` with a sticky sidebar nav, scrollspy, lightbox, and one section per page.
4. **Output** lives at `s3://{disk}/{prefix}/{env}/{panel}/{version}/` with a top-level `index.html` and `{slug}/{viewport}-{mode}.png` per shot.

Install
-------

[](#install)

This is a development tool — most consumers will want it as a `require-dev` dependency so it never ships to production:

```
composer require --dev visualbuilder/filament-screenshot-catalogue
```

(If you genuinely need the artisan commands available in production — e.g. you run captures from a CI job that mounts production-like infrastructure — drop the `--dev` flag.)

The package's commands auto-register. Then make sure both Composer and Node prerequisites are in place:

DependencyWhy it's neededHow to install`aws/aws-sdk-php` + an S3 diskUploads + serves the catalogueAlready pulled in transitively. Configure an S3 disk in `config/filesystems.php` (default expected name: `s3_public`).Node 18+Runs the Playwright runnerSystem-level (`apt install nodejs` / `brew install node` / etc.).PlaywrightDrives the headless browser`npm install playwright && npx playwright install chromium` in the host project root.A canonical "screenshot user" per panelThe runner logs in as this user and the sitemap generator uses them to find sample recordsSeeded by the host (see *Panel registration* below).Optionally publish the config, the Node runner, or the bundled Claude Code skill:

```
php artisan vendor:publish --tag=filament-screenshot-catalogue-config         # override defaults
php artisan vendor:publish --tag=filament-screenshot-catalogue-js             # custom Playwright runner
php artisan vendor:publish --tag=filament-screenshot-catalogue-claude-skills  # /screenshot-catalogue slash command
```

The Claude skill installs into the host's `.claude/commands/screenshot-catalogue.md` — gives Claude the full command surface, troubleshooting tips, and the `PanelDescriptor` registration pattern as context.

Panel registration
------------------

[](#panel-registration)

Hosts tell the package which panels to capture by registering a `PanelDescriptor` per panel — typically inside a small service provider:

```
namespace App\Providers;

use Filament\Facades\Filament;
use Illuminate\Support\ServiceProvider;
use Visualbuilder\FilamentScreenshotCatalogue\PanelDescriptor;
use Visualbuilder\FilamentScreenshotCatalogue\PanelRegistry;

class ScreenshotCatalogueServiceProvider extends ServiceProvider
{
    public function boot(): void
    {
        PanelRegistry::register(new PanelDescriptor(
            key:           'admin',
            panelId:       'admin',
            domain:        env('ADMIN_DOMAIN'),
            loginHeading:  'Admin Login',
            email:         env('SCREENSHOT_ADMIN_EMAIL'),
            password:      env('SCREENSHOT_ADMIN_PASSWORD'),
            authenticator: static function (): void {
                $user = \App\Models\User::where('email', config('catalogue.admin_email'))->first();
                if ($user !== null) auth('web')->setUser($user);
            },
        ));
    }
}
```

Add the provider to `bootstrap/providers.php`. **If you installed the package as `require-dev`** (the default suggestion above), wrap the registration in a `class_exists` check so production — where the package isn't installed — silently skips it instead of crashing on a missing class import:

```
// bootstrap/providers.php

$providers = [
    // ...your usual providers...
];

if (class_exists(\Visualbuilder\FilamentScreenshotCatalogue\PanelRegistry::class)) {
    $providers[] = App\Providers\ScreenshotCatalogueServiceProvider::class;
}

return $providers;
```

If you installed as a regular `require` dependency, register the provider unconditionally.

**Tenanted panels** (Filament's tenancy enabled): set the active tenant inside `authenticator`:

```
authenticator: static function (): void {
    $user = \App\Models\OrganisationUser::where('email', 'sample@example.com')->first();
    if ($user !== null) {
        auth('organisation_user')->setUser($user);
        Filament::setTenant($user->organisation);
    }
},
```

Configuration
-------------

[](#configuration)

Override defaults by publishing `config/screenshot-catalogue.php`. Common knobs:

```
return [
    // S3 disk (must be configured in config/filesystems.php).
    'disk' => 's3_public',

    // Top-level S3 prefix.
    'path_prefix' => 'screenshots',

    // Capture viewports — name → { name, width, height }. Override to
    // standardise on your own breakpoints.
    'viewports' => [
        'desktop' => ['name' => 'desktop', 'width' => 1280, 'height' => 800],
        'tablet'  => ['name' => 'tablet',  'width' => 768,  'height' => 1024],
        'mobile'  => ['name' => 'mobile',  'width' => 375,  'height' => 812],
    ],

    // CSS injected into every page just before the screenshot fires —
    // use this to lock host theme animations into a stable state. Empty
    // by default.
    //
    // Example for a theme that animates its topbar on root scroll:
    //
    // 'capture_time_css' => '
    //     .fi-topbar { padding-block: 1rem !important; }
    //     .fi-main { padding-top: 7rem !important; }
    // ',
    'capture_time_css' => '',

    // Sitemap entries to omit from the catalogue. Match the `slug` field
    // in `storage/app/sitemap-{panel}.json` — Filament's `{resource}.{page}`
    // form (e.g. `users.index`, `orders.edit`) for resource pages, or the
    // page class slug for custom pages. NOT URL slugs.
    'excluded_slugs' => [],

    // Brand assets uploaded next to index.html so the catalogue's heading
    // shows your wordmark + favicon. Both are optional.
    'brand' => [
        'name'    => 'Panel Screenshots',
        'logo'    => public_path('media/your_logo_dark_mode.svg'),
        'favicon' => public_path('media/your_favicon.svg'),
    ],
];
```

How the catalogue is laid out on S3
-----------------------------------

[](#how-the-catalogue-is-laid-out-on-s3)

```
{prefix}/{env}/{panel}/{version}/                       (env omitted in production)
├── index.html
├── favicon.svg
├── logo.svg
├── dashboard/
│   ├── desktop-light.png
│   ├── desktop-dark.png
│   ├── tablet-light.png
│   ├── tablet-dark.png
│   ├── mobile-light.png
│   └── mobile-dark.png
├── orders.index/
│   └── …
└── …

```

Tag-versioning: `--tag=latest` overwrites in place (continuous capture), any other tag (e.g. `--tag=v2.5.0`) is treated as immutable.

Commands
--------

[](#commands)

CommandUse it for`panel:sitemap --panel=KEY`Generate `sitemap-{panelId}.json` for the panel. Re-run when routes change.`screenshot:dispatch --panel=KEY --tag=latest`Queue one `CapturePageScreenshotsJob` per sitemap entry plus a final `RebuildScreenshotIndexJob`. Use a queue worker.`screenshot:capture --panel=KEY --page=SLUG --tag=latest`Synchronous run, single page or a few. Useful for debug.`screenshot:rebuild-index --panel=KEY --tag=latest`Re-render `index.html` from the existing PNGs without re-capturing.All four accept `--panel=KEY` where `KEY` is the friendly CLI name registered in the descriptor (e.g. `admin`). The package translates to Filament's internal panel ID for URL/route resolution.

What's *not* in the package (host responsibilities)
---------------------------------------------------

[](#whats-not-in-the-package-host-responsibilities)

- The seeded sample user(s) per panel — the package needs a real user to log in as, but creating one is host territory.
- Theme-specific tweaks beyond `capture_time_css` (e.g. permanent CSS overrides for a custom design system) — keep those in your theme stylesheet.
- Authentication wiring (tenants, magic links, 2FA dismissal) — the descriptor's `authenticator` closure is the seam.

Production safety
-----------------

[](#production-safety)

The package refuses to run `screenshot:capture` and `screenshot:dispatch` when `APP_ENV=production`. The dispatch flow respects `APP_DEBUG=true` too — it bails out so the Laravel debug bar doesn't pollute every shot.

License
-------

[](#license)

GPL-2.0-or-later.

###  Health Score

49

—

FairBetter than 94% of packages

Maintenance95

Actively maintained with recent releases

Popularity24

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity54

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 81% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~1 days

Total

18

Last Release

22d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/98528425?v=4)[Eko UK Limited](/maintainers/ekoukltd)[@ekoukltd](https://github.com/ekoukltd)

---

Top Contributors

[![leeoptima](https://avatars.githubusercontent.com/u/202847690?v=4)](https://github.com/leeoptima "leeoptima (17 commits)")[![cannycookie](https://avatars.githubusercontent.com/u/500822?v=4)](https://github.com/cannycookie "cannycookie (4 commits)")

---

Tags

filamentscreenshotsplaywrightvisualbuilderagenticvisual regression

###  Code Quality

TestsPest

### Embed Badge

![Health badge](/badges/visualbuilder-filament-screenshot-catalogue/health.svg)

```
[![Health](https://phpackages.com/badges/visualbuilder-filament-screenshot-catalogue/health.svg)](https://phpackages.com/packages/visualbuilder-filament-screenshot-catalogue)
```

###  Alternatives

[spatie/laravel-health

Monitor the health of a Laravel application

88011.3M149](/packages/spatie-laravel-health)[laravel/horizon

Dashboard and code-driven configuration for Laravel queues.

4.1k91.3M277](/packages/laravel-horizon)[spatie/laravel-responsecache

Speed up a Laravel application by caching the entire response

2.8k8.7M64](/packages/spatie-laravel-responsecache)[illuminate/broadcasting

The Illuminate Broadcasting package.

7126.9M199](/packages/illuminate-broadcasting)[spatie/laravel-export

Create a static site bundle from a Laravel app

670139.5k6](/packages/spatie-laravel-export)[flarum/core

Delightfully simple forum software.

261.4M2.2k](/packages/flarum-core)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
