Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Filament Session Replay Laravel Package

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.

View on GitHub
Deep Wiki
Context7

Getting Started

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.

  1. Require the package and run its install steps: publish config/assets if provided and run migrations for the recordings table.
  2. Register SessionReplayPlugin on the Filament panel where you want recordings:
    ->plugin(
        SessionReplayPlugin::make()
            ->record()
            ->resource()
    )
    
  3. Confirm the panel’s guard user model is the person you expect, and that tenancy is configured if the panel is tenant-scoped. The recorder uses the panel guard user, Filament tenant, panel id and impersonator.
  4. Open the generated Sessions resource, then open a recording’s Watch page. That page is the main day-to-day surface: facts, player, markers, Pin, Delete and Export.
  5. Add 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.

Implementation Patterns

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.

Gotchas and Tips

  • Beta churn: pin 1.0.0-beta.1 and read upgrade notes on every beta. Names and config may change before 1.0.
  • Watched pages are not recorded: do not expect a replay of the replay watch page, and do not use it to debug the player itself.
  • Masking is opt-in per field: a missed column or infolist entry can leak PII into recordings. Audit resources, relation managers, widgets and custom layouts before production.
  • Gate vs policy precedence: a registered ReplaySession policy takes over from viewSessionReplay. If access changes after installing Shield or a policy, check both, plus deleteSessionReplay for deletion.
  • Bulk delete is per-recording: the confirmation asks about every selected recording and authorization is checked per item. Large selections can be slow and may partially fail; expect partial deletion and handle it in UX.
  • Export authorization is stricter than it looks: it asks the gate as well as the policy, similar to core data routes. A user who can view a session may still be unable to export it.
  • Impersonation is only auto-detected for Packstub: without impersonatorUsing(), the impersonated filter and recorded impersonator context will be wrong for other switchers.
  • Search is not a join: 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.
  • Tenant scoping changes list shape: in a tenanted panel lists are scoped to the current workspace; outside tenancy a Workspace column appears. Test both panel types if you share resources.
  • Watch storage size: recordings include pages, events, markers and stylesheets, and the resource exposes size. Use the error, poor vitals, rage click, device, first page and date filters to find noisy sessions, then pin or delete. Add pruning/retention around the package’s delete flow rather than assuming indefinite storage.
  • Corrupt/partial chunks: Export deliberately omits a stored chunk that is not a JSON array. If exports look incomplete, inspect the recording’s stored chunks and recording lifecycle rather than the player first.
  • Localization is available but beta: English, German, Spanish, Romanian and Russian are included. Publish/override translations only after confirming the package’s translation namespace, since it may change before 1.0.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core