jeffersongoncalves/filament-pixel
A Filament plugin by Jefferson Gonçalves that integrates Meta Pixel tracking into Laravel admin panels. Designed for developers, it lets you configure pixel IDs, inject tracking code, and capture conversion events from Filament pages, forms, and custom components with minimal setup and flexible even...
Architecture fit
Panel::plugin() registration in a PanelProvider, which is the same extension seam Filament itself uses for first-party plugins. It does not introduce a parallel bootstrapping path, a custom service container binding, or a bespoke asset pipeline, so it composes cleanly with an existing panel provider stack.PixelPlugin (implements Filament\Contracts\Plugin) — registers a render hook and a settings page.PixelServiceProvider — registers PanelsRenderHook::HEAD_START with a pixel::script view.ManagePixelSettings — a Filament settings page backed by spatie/laravel-settings, persisting the Pixel ID..env or a per-panel config array. That is a deliberate product decision: it makes the Pixel ID operator-editable from the admin UI without a deploy. The trade-off is that a runtime-editable value now controls a third-party script injected into every admin page, which shifts change control from release management to whoever holds that page's authorization.jeffersongoncalves/laravel-pixel ^2.0 plus filament/spatie-laravel-settings-plugin ^5.0. Two transitively-versioned third-party packages, both from the same single-maintainer ecosystem, sit between us and working behavior.Integration feasibility
composer require, publish settings migrations (--tag=pixel-settings-migrations), php artisan migrate, register the plugin. Realistically a half-day including review.spatie/laravel-settings requires a settings table (and per-settings-class migrations). This is a schema change to the host application, not a zero-migration install. It needs to go through normal DBA/release review and will collide with any existing settings migrations if the estate already uses this pattern — table-level conflicts are unlikely, but migration ordering and migrate:fresh seeding behavior need checking.PixelPlugin::make()->settingsPage(false) for script-only injection, and the newer navigationGroup(string|Closure) to place the settings page inside an existing panel navigation group.Technical risk
Overall: medium-to-high for a package of this footprint, driven almost entirely by non-code factors rather than implementation quality.
HEAD_START-injected inline <script> from connect.facebook.net will be blocked unless script-src is extended and connect-src permits Meta endpoints. Symptom is silent: no error to the user, just no data. Budget for a CSP change request, which is often a slower approval path than the code change.navigationGroup() as requiring filament-analytics-core 3.1 — a dependency that does not appear anywhere in the documented requirement set (laravel-pixel ^2.0, filament/spatie-laravel-settings-plugin ^5.0). The release note also uses Vendor\Package\Plugin placeholders while the skill documentation uses PixelPlugin. Either the release note was generated from a template, or the package has a third dependency that is undocumented. This is unresolvable from the supplied material and must be closed before approval — if a transitive constraint exists, it interacts with the Filament 5 gate and could produce a resolution deadlock.composer.json visible. Without a pinned ^ constraint set we cannot reason about upgrade safety. Require an explicit lockfile review.Key questions
script-src/connect-src allowlist change, and what is the lead time?composer.json constraint set — specifically, does filament-analytics-core appear as a dependency, and at what version? Is laravel-pixel pinned to ^2.0 or looser?navigationGroup() terminal per plugin instance, and what is the closure's evaluation context (panel, tenant, user)? Is it safe for multi-tenant conditional grouping?Stack fit
spatie/laravel-settings machinery in the host app. If the estate already uses that pattern, fit improves and marginal cost drops; if it does not, we are introducing a persistence convention for a single settings page, which is disproportionate and will invite pushback on the architecture review.Migration path
composer require jeffersongoncalves/filament-pixel in a branch.php artisan vendor:publish --tag=pixel-settings-migrations → review the generated migration before running it (do not blind-run vendor migrations in a regulated schema).php artisan migrate in the target environment; verify rollback works.PixelPlugin::make() in the panel provider.<head> in a browser, verify the network call to Meta succeeds under the production CSP.Compatibility
filament/spatie-laravel-settings-plugin ^5.0 implies a Filament 5-era release line. If the estate has any other plugin pinned to the Filament 4 line of that package, Composer will deadlock. Audit the full plugin set for Filament 5 readiness before committing to a date — this plugin will not be the bottleneck, but it will be the thing blamed when the resolution fails.settings table from another package.Sequencing
filament-analytics-core question by reading composer.json directly.script-src/connect-src amendment request, plus a supply-chain check on a 0-dependent, 5-star package (lockfile pin, no dev- constraints, vendor source review — it is a few hundred lines, read it).settingsPage(false) initially to keep the surface minimal, and the snippet verified end-to-end in the browser. Explicitly confirm staging does not fire the production pixel.navigationGroup() into an existing "Analytics" or "Settings" group — use the exact display label, and register that group in Panel::navigationGroups() so ordering and collapse behave. Use a closure only where tenant/locale logic genuinely requires it.Maintenance
filament-pixel → laravel-pixel → upstream) with a single maintainer at every link, into a panel that must stay on a supported Filament major. When Filament 6 lands, this package's upgrade timeline is entirely outside our control, and a stall blocks our own framework upgrades. For a tracking feature, that is a poor trade — it converts a nice-to-have into a ceiling on the platform roadmap.Support
<head> → plugin not registered on that panel, or render hook suppressed by another plugin.settingsPage(false) set, navigation permission, or migration not run.settings table or per-settings-class migration missing.Scaling
spatie/laravel-settings caches.connect.facebook.net to an admin panel means every page load now waits on (or at least contends with) an external origin. If Meta is slow or blocked at the network edge, admins on restrictive corporate networks or VPNs may see degraded perceived performance. Load it asynchronously and confirm the snippet does not block first paint.navigationGroup() closure is used, keep it pure — a closure that queries the database will multiply across every authenticated page load in the panel. Enforce this in code review.Failure modes
navigationGroup() closure that throws or returns an unexpected type breaks panel navigation rendering — high blast radius (the whole admin panel), which is disproportionate to a cosmetic grouping choice. Mitigation: prefer a static string; use a closure only with null-safe access and no I/O; test the panel boots in CI.Panel::navigationGroups(), reviewed in staging.spatie-laravel-settings, or the undocumented filament-analytics-core floor) surfaces only at install time, potentially mid-sprint. Mitigation: resolve dependencies in a throwaway branch before committing the sprint.Ramp-up
How can I help you explore Laravel packages today?