solution-forest/filament-simplelightbox
Filament SimpleLightbox adds a lightweight, responsive lightbox viewer for images in your Filament panels. Open table, infolist, and form images in an elegant gallery with keyboard navigation, minimal setup, and no heavy dependencies.
Confirm compatibility before anything else. This is a small, lightly-used package maintained by a single organisation, so treat the version constraint in its composer.json as the source of truth: check which Filament major it targets (filament/filament: ^3.0 vs ^4.0) and pin the package to an exact version ("solution-forest/filament-simplelightbox": "1.1.1", not ^1.1). Filament's component base classes moved between v3 and v4 (Filament\Forms\Components → schema classes), and a plugin this small will not carry a compatibility shim.
As of 1.1.1 the package advertises Laravel 13 support (PR #41), and the rest of the release is Dependabot CI churn — no PHP/Blade/JS changes. That means the 1.1.0 → 1.1.1 bump is safe, but it also means the Filament-major question is unchanged: if you were on 1.1.0 and it worked, 1.1.1 will too.
composer require solution-forest/filament-simplelightbox
php artisan vendor:publish --tag=filament-simplelightbox-assets # if the tag exists
php artisan filament:assets # belt and braces
If the package ships a plugin object, register it in your panel provider:
public function panel(Panel $panel): Panel
{
return $panel->plugin(SimpleLightboxPlugin::make());
}
Where to look first, in this order:
README.md — usually one usage snippet; copy it verbatim.src/ — list the classes. Whatever slot the package targets decides your entry point: a Forms\Components\* class means form fields, a Tables\Columns\* class means table columns, an Infolists\Entries\* class means read-only detail views. Many small Filament plugins ship only one of these.resources/views/ — this is where SimpleLightbox actually gets booted. Read the Blade file; it tells you the exact DOM contract (anchors with href, a wrapper with a class selector) and which JS options are exposed.src/*ServiceProvider.php — shows FilamentAsset::register() calls and any publishable config/views, which is your list of extension points.First use case to validate the install: an image gallery on a Resource view page. Add the package's component to a form next to a FileUpload/SpatieMediaLibraryFileUpload, upload two or three images, and click a thumbnail. If a full-screen overlay appears with prev/next arrows, the JS asset is loading and the component is wired correctly. If clicking navigates the browser to the raw image URL instead, the JS never booted — go straight to the console (see Gotchas).
Pair it with a media uploader, not raw file paths. The component almost certainly takes an array of URLs; the work is producing that array reliably. With Spatie Media Library:
use SolutionForest\SimpleLightbox\...; // confirm namespace from src/
SpatieMediaLibraryFileUpload::make('gallery')
->collection('gallery')
->multiple()
->image(),
// lightbox component fed from the same record
YourLightboxComponent::make('gallery')
->images(fn ($record) => $record
->getMedia('gallery')
->map(fn ($m) => $m->getUrl('thumb')) // thumb for src, original for href
->all()),
If the component reads $state directly, put it after the upload field in the schema so state is populated on re-render.
Group multiple items into one gallery. The main reason to use a lightbox over a plain image column is arrow-navigation across a set. Whether that's a ->group('gallery'), a shared CSS class, or SimpleLightbox's own data- attributes depends on the package's API — look for a group/collection/album-style method. Without one, all images on the page will likely be treated as a single set (or each isolated), so test with two separate galleries on one page early.
Use it in all three slots if available. The same visual affordance is worth having in a table (ImageColumn replacement for a media collection) and in an infolist entry on the View page. Consistency between the list and the detail view is the whole point of the package — if it only covers forms, consider whether an Infolist entry plus a custom Blade partial gets you the rest.
Override the view rather than fight the component. For anything the fluent API doesn't cover (captions, download links, custom close button), publish the views (vendor:publish --tag=filament-simplelightbox-views) or point at your own with ->view('components.my-lightbox'). Keep the published copy in resources/views/vendor/... so package updates don't silently overwrite your edits.
Theme via SimpleLightbox's own CSS variables in your panel's custom theme (->viteTheme()), not by editing published package CSS. That survives upgrades. Add the overrides after Filament's base CSS loads.
Register a custom JS file through FilamentAsset::register([Js::make('lightbox-init', __DIR__.'/../dist/lightbox.js')], package: 'app') if you need to pass options (i18n strings, nav, captionsData) that the PHP API doesn't expose. Pass them via data- attributes on the wrapper from the Blade view and read them in the init script.
Asset loading is the number-one failure mode. A lightbox package is 95% JavaScript, and a small package frequently gets the PHP side right and the asset registration subtly wrong — especially for production builds where filament:assets / php artisan vendor:publish is a deploy step. Symptom: thumbnails render, clicks navigate away. Fix: view source, confirm the <script> tag for simplelightbox is present, and confirm the file exists under public/. Add the publish command to your deploy script, not just your local setup.
Livewire morphing will break the lightbox. Alpine/Livewire re-renders replace DOM nodes; a lightbox initialised on DOMContentLoaded binds to nodes that no longer exist. If the package's view uses x-init, you're fine. If it uses a one-shot new SimpleLightbox(...) on page load, wrap your own init and re-run it on livewire:navigated, morph.updated, and after any form action that rebuilds the gallery. Also destroy the old instance to avoid stacked overlays.
Disk and URL correctness. Use getUrl() from the media model, not string concatenation on the path. Ensure the disk is public with visibility public, and that php artisan storage:link has run. A lightbox that opens a 404 image is almost always a storage link or visibility issue, not a package bug.
Serve two sizes. Feeding the original 4MB upload into both the thumbnail <img src> and the lightbox href makes galleries sluggish. Generate a thumb conversion for the grid and use the original only in the overlay. If the package hardcodes one URL for both, that's a strong reason to override the view.
Version drift is a real risk here. The package has almost no downstream dependents, so it is lightly exercised by the ecosystem. Read the diff of every release before bumping. The 1.1.1 release is a good example of a "nothing to see" release: Dependabot bumps to ramsey/composer-install and dependabot/fetch-metadata, plus a Laravel 13 support PR — all CI and constraint metadata, no src/ or resources/ changes. Still run git diff 1.1.0 1.1.1 -- src resources (or git diff between tags in vendor/ after composer update) rather than trusting release notes alone; a constraint bump in composer.json can silently change which packages resolve. Commit composer.lock. If you're on Filament v4 and the package targets v3, don't try to shim it: forking the 200-line view into your own Blade partial and calling SimpleLightbox directly from Alpine is often less work than the upgrade.
Debugging checklist, in order: browser console for SimpleLightbox is not defined (asset missing) → inspect a thumbnail's rendered markup, confirm it's an <a href="..."> wrapping an <img>, not a bare <img> (the library needs the anchor) → confirm the selector in the init script matches the actual wrapper class → check that the container isn't inside a wire:ignore or hidden tab that defers rendering.
Accessibility and i18n. SimpleLightbox ships localisation strings and keyboard navigation, but they must be passed through as JS options. If the PHP API doesn't expose them, that's your first custom-view override — it's a small change with a large payoff for non-English panels. Also verify focus trapping and aria-labels on the close button; small plugins often skip this, and it's cheap to add in your override.
Extension points to keep in mind: publishable views (safe overrides), publishable config if present, ->extraAttributes() on the component for data-* passthrough, and FilamentAsset::register(..., package: 'solution-forest/filament-simplelightbox') to append your own CSS/JS without replacing the package's.
How can I help you explore Laravel packages today?