packstub/filament-session-replay
Filament Session Replay is a Filament plugin for recording and reviewing admin panel sessions, helping you understand user behavior and debug issues faster with replay access built into your dashboard.
Pin the beta exactly in composer.json (for example "vendor/package": "1.0.0-beta.1"). This is a first beta, so treat config keys and class names as unstable until 1.0.
SessionReplayPlugin on the Filament panel where you want recordings:
->plugin(
SessionReplayPlugin::make()
->record()
->resource()
)
WatchLastSessionAction and ReplayStatsWidget to a user table/dashboard for the quickest “support engineer” workflow.First real use case: reproduce a user-reported bug by filtering Sessions for errors or rage clicks, watching the latest recording, noting the first page, device and vitals, then exporting the JSON for a ticket.
Enable recording per panel, not globally by accident. Use record() only on panels whose pages should be captured. The plugin hooks into rendering, so it applies to panel pages automatically; watched replay pages are excluded by design.
Treat masking as a required resource audit. Add maskInReplay() to sensitive form fields, table columns, infolist entries and layout components; use blockInReplay() where the value must not appear at all:
TextInput::make('email')->maskInReplay(),
TextInput::make('api_token')->blockInReplay(),
Wire authorization before exposing the resource. Define viewSessionReplay for the core gate, and add a ReplaySession policy when you need per-record rules. A registered policy takes over from the gate; define deleteSessionReplay if deletion should be separate from viewing. Export checks both the gate and policy, so test both paths.
Use visibility rules for list narrowing. Start lists from SessionReplay::visibleUsing() if certain recordings should never appear in the resource, relation manager, widget or WatchLastSessionAction. Keep this in SQL-friendly form; it applies to every list, not just the Watch page.
Add people-centric entry points. In a User resource, add ReplaysRelationManager; on tables, add WatchLastSessionAction; on dashboards, register ReplayStatsWidget. In tenanted panels these keep to the current workspace automatically.
Configure impersonation detection. Packstub’s Account Switcher is detected automatically. For any other impersonation package, use impersonatorUsing() so the “impersonated” filter and recorded context are correct.
Configure people search deliberately. The Sessions search checks the recorded person’s own table rather than joining. Use searchPeopleBy() per model to point at the right name/email columns, especially if your schema differs from Laravel defaults.
Use tenancy labels where tenants lack name. In tenanted panels the resource, person tab, widget and action scope to the current workspace. Outside tenancy, a Workspace column appears; use tenantLabelUsing() to give tenants a readable label.
Export for support, not as a data pipeline. The Watch page Export produces one JSON file with events, markers and stylesheets. It skips a stored chunk that is not a JSON array, so exported files may be partial when recordings are corrupt or still being written.
1.0.0-beta.1 and read upgrade notes on every beta. Names and config may change before 1.0.ReplaySession policy takes over from viewSessionReplay. If access changes after installing Shield or a policy, check both, plus deleteSessionReplay for deletion.impersonatorUsing(), the impersonated filter and recorded impersonator context will be wrong for other switchers.searchPeopleBy() searches columns on the recorded person’s own table. Encrypted columns, accessors or non-standard schemas need explicit configuration; the exact key search still works alongside it.How can I help you explore Laravel packages today?