PHPackages                             chengkangzai/filament-shot - 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. chengkangzai/filament-shot

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

chengkangzai/filament-shot
==========================

Render Filament v4/v5 UI components (Forms, Tables, Infolists, Stats Widgets) as PNG images programmatically.

v0.9.3(4w ago)0485↓60.2%[7 issues](https://github.com/chengkangzai/filament-shot/issues)MITHTMLPHP ^8.2CI failing

Since Mar 4Pushed 4w agoCompare

[ Source](https://github.com/chengkangzai/filament-shot)[ Packagist](https://packagist.org/packages/chengkangzai/filament-shot)[ Docs](https://github.com/chengkangzai/filament-shot)[ GitHub Sponsors](https://github.com/CCK)[ RSS](/packages/chengkangzai-filament-shot/feed)WikiDiscussions master Synced 3w ago

READMEChangelog (10)Dependencies (42)Versions (97)Used By (0)

Filament Shot
=============

[](#filament-shot)

[![Latest Version on Packagist](https://camo.githubusercontent.com/e8412dcbed9644a6fd6f592c86c104f4e745abcc2c832334befa06cfbbdc6f89/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6368656e676b616e677a61692f66696c616d656e742d73686f742e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/chengkangzai/filament-shot)[![GitHub Tests Action Status](https://camo.githubusercontent.com/803a24b25604b0b7d926d50c9e83df5938acc51ec6fe06adf6e496742d1a82ec/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f6368656e676b616e677a61692f66696c616d656e742d73686f742f72756e2d74657374732e796d6c3f6272616e63683d6d6173746572266c6162656c3d7465737473267374796c653d666c61742d737175617265)](https://github.com/chengkangzai/filament-shot/actions?query=workflow%3Arun-tests+branch%3Amaster)[![Total Downloads](https://camo.githubusercontent.com/0f937a5cc0a254c32a25b23507cd24a7874b2c9ed1955808848b159e5cd1fb9b/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6368656e676b616e677a61692f66696c616d656e742d73686f742e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/chengkangzai/filament-shot)

Render Filament v4/v5 UI components — Forms, Tables, Infolists, and Stats Widgets — as PNG screenshots programmatically. Define your components using familiar Filament classes and get pixel-perfect images without spinning up a browser manually.

Examples
--------

[](#examples)

These screenshots are generated by CI using the actual rendering pipeline to verify quality.

### Forms

[](#forms)

LightDark[![Form Light](https://raw.githubusercontent.com/chengkangzai/filament-shot/0492bcf/examples/images/form-light.png)](https://raw.githubusercontent.com/chengkangzai/filament-shot/0492bcf/examples/images/form-light.png)[![Form Dark](https://raw.githubusercontent.com/chengkangzai/filament-shot/0492bcf/examples/images/form-dark.png)](https://raw.githubusercontent.com/chengkangzai/filament-shot/0492bcf/examples/images/form-dark.png)Section LayoutGrid Layout[![Form Section](https://raw.githubusercontent.com/chengkangzai/filament-shot/0492bcf/examples/images/form-section.png)](https://raw.githubusercontent.com/chengkangzai/filament-shot/0492bcf/examples/images/form-section.png)[![Form Grid](https://raw.githubusercontent.com/chengkangzai/filament-shot/0492bcf/examples/images/form-grid.png)](https://raw.githubusercontent.com/chengkangzai/filament-shot/0492bcf/examples/images/form-grid.png)Additional Field Types[![Form Fields](https://raw.githubusercontent.com/chengkangzai/filament-shot/0492bcf/examples/images/form-fields.png)](https://raw.githubusercontent.com/chengkangzai/filament-shot/0492bcf/examples/images/form-fields.png)TabsWizard[![Form Tabs](https://raw.githubusercontent.com/chengkangzai/filament-shot/master/examples/images/form-tabs.png)](https://raw.githubusercontent.com/chengkangzai/filament-shot/master/examples/images/form-tabs.png)[![Form Wizard](https://raw.githubusercontent.com/chengkangzai/filament-shot/master/examples/images/form-wizard.png)](https://raw.githubusercontent.com/chengkangzai/filament-shot/master/examples/images/form-wizard.png)Color Picker[![Form Color Picker](https://raw.githubusercontent.com/chengkangzai/filament-shot/master/examples/images/form-color-picker.png)](https://raw.githubusercontent.com/chengkangzai/filament-shot/master/examples/images/form-color-picker.png)### Tables

[](#tables)

BasicWith Badges[![Table Basic](https://raw.githubusercontent.com/chengkangzai/filament-shot/0492bcf/examples/images/table-basic.png)](https://raw.githubusercontent.com/chengkangzai/filament-shot/0492bcf/examples/images/table-basic.png)[![Table Badges](https://raw.githubusercontent.com/chengkangzai/filament-shot/0492bcf/examples/images/table-badges.png)](https://raw.githubusercontent.com/chengkangzai/filament-shot/0492bcf/examples/images/table-badges.png)Styled (Weight + Mono Font)Dark Mode[![Table Styled](https://raw.githubusercontent.com/chengkangzai/filament-shot/0492bcf/examples/images/table-styled.png)](https://raw.githubusercontent.com/chengkangzai/filament-shot/0492bcf/examples/images/table-styled.png)[![Table Dark](https://raw.githubusercontent.com/chengkangzai/filament-shot/0492bcf/examples/images/table-dark.png)](https://raw.githubusercontent.com/chengkangzai/filament-shot/0492bcf/examples/images/table-dark.png)Icon Column (Boolean)Bulk Actions[![Table Icon Column](https://raw.githubusercontent.com/chengkangzai/filament-shot/0492bcf/examples/images/table-icon-column.png)](https://raw.githubusercontent.com/chengkangzai/filament-shot/0492bcf/examples/images/table-icon-column.png)[![Table Bulk Actions](https://raw.githubusercontent.com/chengkangzai/filament-shot/master/examples/images/table-bulk-actions.png)](https://raw.githubusercontent.com/chengkangzai/filament-shot/master/examples/images/table-bulk-actions.png)ReorderableAction Group[![Table Reorderable](https://raw.githubusercontent.com/chengkangzai/filament-shot/master/examples/images/table-reorderable.png)](https://raw.githubusercontent.com/chengkangzai/filament-shot/master/examples/images/table-reorderable.png)[![Table Action Group](https://raw.githubusercontent.com/chengkangzai/filament-shot/master/examples/images/table-action-group.png)](https://raw.githubusercontent.com/chengkangzai/filament-shot/master/examples/images/table-action-group.png)### Infolist

[](#infolist)

LightDark[![Infolist](https://raw.githubusercontent.com/chengkangzai/filament-shot/0492bcf/examples/images/infolist.png)](https://raw.githubusercontent.com/chengkangzai/filament-shot/0492bcf/examples/images/infolist.png)[![Infolist Dark](https://raw.githubusercontent.com/chengkangzai/filament-shot/0492bcf/examples/images/infolist-dark.png)](https://raw.githubusercontent.com/chengkangzai/filament-shot/0492bcf/examples/images/infolist-dark.png)### Navigation

[](#navigation)

Sidebar[![Navigation](https://raw.githubusercontent.com/chengkangzai/filament-shot/master/examples/images/navigation.png)](https://raw.githubusercontent.com/chengkangzai/filament-shot/master/examples/images/navigation.png)### Stats Widgets

[](#stats-widgets)

LightDark[![Stats](https://raw.githubusercontent.com/chengkangzai/filament-shot/0492bcf/examples/images/stats.png)](https://raw.githubusercontent.com/chengkangzai/filament-shot/0492bcf/examples/images/stats.png)[![Stats Dark](https://raw.githubusercontent.com/chengkangzai/filament-shot/0492bcf/examples/images/stats-dark.png)](https://raw.githubusercontent.com/chengkangzai/filament-shot/0492bcf/examples/images/stats-dark.png)### Notifications

[](#notifications)

Success[![Notification](https://raw.githubusercontent.com/chengkangzai/filament-shot/master/examples/images/notification.png)](https://raw.githubusercontent.com/chengkangzai/filament-shot/master/examples/images/notification.png)How It Works
------------

[](#how-it-works)

Filament Shot generates standalone HTML using its own Blade templates styled with Filament's CSS classes, then captures screenshots via [Browsershot](https://github.com/spatie/browsershot). This avoids Livewire context issues entirely — no running application or panel required.

Requirements
------------

[](#requirements)

- PHP 8.2+
- Laravel 11+
- Filament v4 or v5
- Node.js 18+ and [Puppeteer](https://pptr.dev/)
- A Chromium-based browser (Chrome, Chromium, etc.)

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

[](#installation)

Install the package via Composer:

```
composer require chengkangzai/filament-shot
```

Install Puppeteer (required by Browsershot):

```
npm install puppeteer
```

Publish the config file (optional):

```
php artisan vendor:publish --tag="filament-shot-config"
```

Usage
-----

[](#usage)

### Forms

[](#forms-1)

Capture Filament form components as an image:

```
use CCK\FilamentShot\FilamentShot;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\Toggle;

FilamentShot::form([
    TextInput::make('name')
        ->label('Full Name')
        ->placeholder('Enter your name'),
    TextInput::make('email')
        ->label('Email Address')
        ->placeholder('you@example.com'),
    Select::make('role')
        ->label('Role')
        ->options([
            'admin' => 'Administrator',
            'editor' => 'Editor',
            'viewer' => 'Viewer',
        ]),
    Toggle::make('active')
        ->label('Active'),
])
->state(['name' => 'Jane Doe', 'email' => 'jane@example.com'])
->save('form.png');
```

Supported field types: `TextInput`, `Select`, `Textarea`, `Toggle`, `Checkbox`, `Radio`, `Placeholder`, `DatePicker`, `DateTimePicker`, `FileUpload`, `ColorPicker`, `TagsInput`, `KeyValue`, `RichEditor`, `MarkdownEditor`, `Repeater`.

Layout components: `Section`, `Grid`, `Fieldset`, `Tabs`, `Wizard`.

#### Forms with Tabs

[](#forms-with-tabs)

```
use CCK\FilamentShot\FilamentShot;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle;
use Filament\Schemas\Components\Tabs;
use Filament\Schemas\Components\Tabs\Tab;

FilamentShot::form([
    Tabs::make('Settings')
        ->tabs([
            Tab::make('General')
                ->icon('heroicon-o-cog-6-tooth')
                ->schema([
                    TextInput::make('site_name')->label('Site Name'),
                    TextInput::make('site_url')->label('Site URL'),
                ]),
            Tab::make('Notifications')
                ->icon('heroicon-o-bell')
                ->schema([
                    Toggle::make('email_notifications')->label('Email Notifications'),
                ]),
        ]),
])
->state(['site_name' => 'My App', 'site_url' => 'https://myapp.com'])
->save('form-tabs.png');
```

Use `->activeTab(2)` to render a specific tab as active.

#### Forms with Wizard Steps

[](#forms-with-wizard-steps)

```
use CCK\FilamentShot\FilamentShot;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle;
use Filament\Schemas\Components\Wizard;
use Filament\Schemas\Components\Wizard\Step;

FilamentShot::form([
    Wizard::make([
        Step::make('Account')
            ->description('Your credentials')
            ->schema([
                TextInput::make('email')->label('Email'),
                TextInput::make('password')->label('Password'),
            ]),
        Step::make('Profile')
            ->description('Personal info')
            ->schema([
                TextInput::make('name')->label('Full Name'),
            ]),
        Step::make('Review')
            ->description('Confirm details')
            ->schema([
                Toggle::make('terms')->label('I accept the terms'),
            ]),
    ]),
])
->state(['email' => 'jane@example.com'])
->width(900)
->save('form-wizard.png');
```

Use `->startOnStep(2)` to render a specific step as active (previous steps show as completed).

#### Forms with Layout Components

[](#forms-with-layout-components)

```
use CCK\FilamentShot\FilamentShot;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle;
use Filament\Schemas\Components\Section;

FilamentShot::form([
    Section::make('Personal Information')
        ->schema([
            TextInput::make('name')->label('Full Name'),
            TextInput::make('email')->label('Email'),
        ]),
    Section::make('Settings')
        ->schema([
            Toggle::make('active')->label('Active'),
        ]),
])
->state(['name' => 'Jane Doe', 'email' => 'jane@example.com', 'active' => true])
->save('form-with-sections.png');
```

### Tables

[](#tables-1)

```
use CCK\FilamentShot\FilamentShot;
use Filament\Tables\Columns\TextColumn;

FilamentShot::table()
    ->columns([
        TextColumn::make('name'),
        TextColumn::make('email'),
        TextColumn::make('role'),
    ])
    ->records([
        ['name' => 'Alice', 'email' => 'alice@example.com', 'role' => 'Admin'],
        ['name' => 'Bob', 'email' => 'bob@example.com', 'role' => 'Editor'],
        ['name' => 'Charlie', 'email' => 'charlie@example.com', 'role' => 'Viewer'],
    ])
    ->heading('Team Members')
    ->striped()
    ->save('table.png');
```

#### Tables with Action Groups (Dropdowns)

[](#tables-with-action-groups-dropdowns)

```
use CCK\FilamentShot\FilamentShot;
use Filament\Actions\Action;
use Filament\Actions\ActionGroup;
use Filament\Tables\Columns\TextColumn;

FilamentShot::table()
    ->columns([
        TextColumn::make('name'),
        TextColumn::make('email'),
    ])
    ->records([
        ['name' => 'Alice', 'email' => 'alice@example.com'],
        ['name' => 'Bob', 'email' => 'bob@example.com'],
    ])
    ->recordActions([
        Action::make('view')->label('View')->icon('heroicon-o-eye'),
        ActionGroup::make([
            Action::make('edit')->label('Edit')->icon('heroicon-o-pencil-square'),
            Action::make('delete')->label('Delete')->icon('heroicon-o-trash')->color('danger'),
        ]),
    ])
    ->save('table-action-group.png');
```

#### Reorderable Tables

[](#reorderable-tables)

```
FilamentShot::table()
    ->columns([
        TextColumn::make('name'),
        TextColumn::make('email'),
    ])
    ->records([
        ['name' => 'Alice', 'email' => 'alice@example.com'],
        ['name' => 'Bob', 'email' => 'bob@example.com'],
    ])
    ->reorderable()
    ->save('table-reorderable.png');
```

#### Tables with Bulk Actions

[](#tables-with-bulk-actions)

```
use CCK\FilamentShot\FilamentShot;
use Filament\Actions\BulkAction;
use Filament\Tables\Columns\TextColumn;

FilamentShot::table()
    ->columns([
        TextColumn::make('name'),
        TextColumn::make('email'),
        TextColumn::make('status')->badge(),
    ])
    ->records([
        ['name' => 'Alice', 'email' => 'alice@example.com', 'status' => 'Active'],
        ['name' => 'Bob', 'email' => 'bob@example.com', 'status' => 'Blocked'],
        ['name' => 'Charlie', 'email' => 'charlie@example.com', 'status' => 'Active'],
    ])
    ->bulkActions([
        BulkAction::make('change_status')
            ->label('Change Status')
            ->icon('heroicon-o-bell')
            ->color('success'),
        BulkAction::make('delete')
            ->label('Delete')
            ->icon('heroicon-o-trash')
            ->color('danger'),
    ])
    ->selectedRows([0, 2]) // indices of rows to show as checked
    ->save('table-bulk-actions.png');
```

### Infolists

[](#infolists)

```
use CCK\FilamentShot\FilamentShot;
use Filament\Infolists\Components\TextEntry;

FilamentShot::infolist([
    TextEntry::make('name')->label('Name'),
    TextEntry::make('email')->label('Email'),
    TextEntry::make('joined')->label('Member Since'),
])
->state([
    'name' => 'Jane Doe',
    'email' => 'jane@example.com',
    'joined' => 'January 2024',
])
->save('infolist.png');
```

### Navigation

[](#navigation-1)

```
use CCK\FilamentShot\FilamentShot;
use Filament\Navigation\NavigationGroup;
use Filament\Navigation\NavigationItem;

FilamentShot::navigation()
    ->items([
        NavigationItem::make('Dashboard')
            ->icon('heroicon-o-home'),
        NavigationGroup::make('Content')
            ->items([
                NavigationItem::make('Posts')
                    ->icon('heroicon-o-document-text')
                    ->isActiveWhen(fn () => true)
                    ->badge('24', 'success'),
                NavigationItem::make('Pages')
                    ->icon('heroicon-o-document'),
            ]),
        NavigationGroup::make('Settings')
            ->items([
                NavigationItem::make('General')
                    ->icon('heroicon-o-cog-6-tooth'),
            ]),
    ])
    ->heading('Admin Panel')
    ->width(320)
    ->save('navigation.png');
```

### Stats Widgets

[](#stats-widgets-1)

```
use CCK\FilamentShot\FilamentShot;
use Filament\Widgets\StatsOverviewWidget\Stat;

FilamentShot::stats([
    Stat::make('Total Users', '1,234')
        ->description('12% increase')
        ->descriptionIcon('heroicon-m-arrow-trending-up')
        ->color('success'),
    Stat::make('Revenue', '$56,789')
        ->description('8% increase')
        ->chart([7, 3, 4, 5, 6, 3, 5, 8]),
    Stat::make('Orders', '456')
        ->description('3% decrease')
        ->descriptionIcon('heroicon-m-arrow-trending-down')
        ->color('danger'),
])
->save('stats.png');
```

### Notifications

[](#notifications-1)

```
use CCK\FilamentShot\FilamentShot;

FilamentShot::notification()
    ->title('Status Updated')
    ->body('The customer status has been changed to Active.')
    ->success()
    ->width(400)
    ->save('notification.png');
```

Output Methods
--------------

[](#output-methods)

Every renderer supports multiple output methods:

```
$renderer = FilamentShot::form([...]);

// Save to disk
$renderer->save('/path/to/screenshot.png');

// Get base64-encoded PNG
$base64 = $renderer->toBase64();

// Get rendered HTML (useful for debugging)
$html = $renderer->toHtml();

// Get an HTTP response with the PNG
return $renderer->toResponse();
```

Customization
-------------

[](#customization)

### Viewport

[](#viewport)

Control the screenshot dimensions and resolution:

```
FilamentShot::form([...])
    ->width(1280)
    ->height(720)
    ->deviceScale(2)  // Retina / HiDPI
    ->save('screenshot.png');
```

### Theme

[](#theme)

Switch between light and dark mode, or set a custom primary color:

```
FilamentShot::form([...])
    ->darkMode()
    ->primaryColor('#3b82f6')
    ->save('dark-form.png');
```

### 3rd-Party Plugin Support

[](#3rd-party-plugin-support)

FilamentShot automatically includes CSS from any Filament plugin registered via `FilamentAsset::register()`. If the plugin's service provider is loaded, its styles will appear in your screenshots — no extra configuration needed.

```
use Ysfkaya\FilamentPhoneInput\Forms\PhoneInput;

FilamentShot::form([
    TextInput::make('name')->label('Name'),
    PhoneInput::make('phone')->label('Phone Number'),
])
    ->state(['name' => 'Jane Doe', 'phone' => '+60123456789'])
    ->width(600)
    ->save('form-with-phone.png');
```

If a plugin's CSS isn't auto-discovered (e.g. it doesn't use Filament's asset pipeline), you can inject it manually using `->css()` or `->cssFile()`:

```
FilamentShot::form([
    TextInput::make('name')->label('Full Name'),
    TextInput::make('phone')->label('Phone Number')->prefix('+60'),
    TextInput::make('email')->label('Email'),
])
    ->state(['name' => 'Jane Doe', 'phone' => '12-345 6789', 'email' => 'jane@example.com'])
    ->css('
        /* Custom plugin styles injected directly */
        .my-plugin-input { border-color: #3b82f6; }
    ')
    ->cssFile('/path/to/vendor/my-plugin/dist/plugin.css')
    ->width(600)
    ->save('form-with-phone.png');
```

[![Form with custom CSS](examples/images/form-custom-css.png)](examples/images/form-custom-css.png)

### Artisan Command

[](#artisan-command)

Capture screenshots from a config file:

```
php artisan filament-shot:capture --config=screenshots.php
```

The config file should return an array of screenshot definitions:

```
