hugomyb/filament-media-action
Filament Media Action lets you display video, audio, PDFs, images and more directly in Filament via an action. It auto-detects file extensions and selects the right player, works in forms, tables and infolists, and supports options like autoplay.
Architecture fit
The package is a thin, presentation-layer addition to an existing Filament panel: one Action class, a Blade modal view, and Alpine-driven loading state. It introduces no tables, migrations, service configuration, or domain coupling — it renders media that already exists at a URL we supply. That gives it a very low blast radius and a cheap exit path (remove the action, delete the package). Where it fits well is media-heavy back-office surfaces: document/compliance evidence review, training or tutorial video links, product asset inspection, and approval workflows where a reviewer needs to see the file before signing off. It also composes with Filament's own primitives (extraModalFooterActions, ->url(), ->openUrlInNewTab()), which means it can be the "viewer" half of a review-and-decide pattern rather than a dead-end widget. It is not a fit for public-facing surfaces, API responses, or anything outside a Filament admin panel — this is an internal-tooling dependency, and should be scoped and budgeted that way.
Integration feasibility
High on paper. composer require, auto-discovery, optional view and translation publishing, usable anywhere Filament Actions are accepted (tables, forms, infolists, prefixes/suffixes). The one hard constraint is Filament major pinning: ^3.0 for Filament v3, latest for v4. That means the package's release cadence becomes a gate on our own framework upgrade cadence. A half-day spike is enough to establish feasibility; the work is not integration effort, it is compatibility validation.
Technical risk
disableDownload() / disableFullscreen() / noremoteplayback are controlsList flags and are explicitly Chromium-only. They must not be evaluated or documented as access controls — the URL is still retrievable..load is not a function fixes. Mobile admin usage is the riskiest path.<embed>, which is CSP-sensitive and inconsistent on mobile.Key questions
frame-src for YouTube, object-src/frame-src for PDF, media-src)?filament:assets / Vite builds?->mediaType() bypass or a proxy route is mandatory.Verdict: adopt conditionally — suitable for internal admin panels, contingent on the spike confirming CSP compatibility, latency without server-side probing, and iOS behaviour. Do not adopt as a default pattern until one low-risk resource has been in production for a release cycle.
Stack fit Laravel 11 + Filament v3/v4 + Livewire + Alpine + Tailwind. The package is PHP, Blade, and Alpine only — no Node build step on our side (verify). It fits an existing Filament panel with zero architectural change; it does not fit Inertia, API, or public web surfaces.
Migration path
Effectively greenfield. No schema change, no data backfill, no cutover — existing media URLs keep working, and records without a URL simply don't render the action (guard with ->visible(fn ($record) => filled($record->url))). The only migration-like concern is Filament major alignment: upgrading Filament forces a package major bump in the same change. Encapsulate usage behind our own thin subclass (e.g. App\Filament\Actions\MediaViewerAction extends MediaAction) so that a swap, fork, or abandonment is a single-file edit rather than a sweep of every resource.
Compatibility
Pin the package major to the Filament major (^3.0 vs. latest) and pin the minor to a version we have tested — the 3.1.1.x line shipped frequent patch releases, so floating on * or dev-main is not acceptable for a production panel. Verify Livewire and PHP version alignment against the installed Filament release before committing.
Sequencing
Maintenance Small code surface, but real dependency maintenance: we inherit a third-party package tracking Filament's majors. Publish the view to insulate against markup churn; keep a fork branch ready. Review every changelog on upgrade rather than relying on semver, and pin to a specific tested patch.
Support Community-only, single maintainer, no SLA. Internal support burden is low but non-zero; the canonical ticket will be "media won't play in the modal." The cheapest resilience tactic is the new-tab fallback action on every instance, which converts a blocked modal into a recoverable user action.
Scaling
Rendering is client-side, so the real scaling load lands on object storage and CDN egress, not app servers — with one exception: if media-type detection probes remote URLs per modal open, every user interaction becomes an outbound request. Mitigate by storing a media_type on the record and passing ->mediaType() explicitly, bypassing detection entirely for known assets. This is a latency and cost lever as much as a scaling one.
Failure modes to instrument or design out
preload(false).Ramp-up Very low. Any developer fluent in Filament Actions is productive in one to two hours; the README plus screenshots cover the API surface. The non-obvious cost is the compatibility testing in the spike, which is browser and CSP work rather than package learning — budget it as QA time, not developer education.
How can I help you explore Laravel packages today?