niek-ph/laravel-visitor-tracking-filament
A Filament plugin for Laravel visitor tracking that adds admin resources and widgets to monitor visits, page views, unique visitors, and online users directly in your Filament panel.
This package is a Filament panel plugin that puts a UI (navigation entries, tables, and typically a stats widget) on top of the data captured by the underlying laravel-visitor-tracking package — visits, sessions, paths, referrers, user agent/geo data. It does not track anything itself; it only reads the tables the base package writes.
Minimum path to a working screen:
composer require niek-ph/laravel-visitor-tracking-filament
php artisan vendor:publish --tag=visitor-tracking # base package migrations/config
php artisan migrate
--tag=filament-visitor-tracking-* — check php artisan vendor:publish output rather than guessing tags).app/Providers/Filament/AdminPanelProvider.php:
->plugin(VisitorTrackingPlugin::make())
php artisan filament:clear-cached-components && php artisan optimize:clear
Where to look first: the plugin class itself (it is the inventory of what gets registered — pages vs. resources vs. widgets, and which fluent options exist), then the resource/page classes it registers, then the base package's config/visitor-tracking.php (retention, bot filtering, IP handling). If the nav item is missing, the plugin class is almost always the answer, not the panel provider.
First use case: open the panel, click the visitor/visit nav entry, filter to today, and drill into a single session to see the ordered path. That one flow tells you whether the recorded data is good enough (bot filtering, geo resolution, session grouping) before you build anything on it.
Register per panel, deliberately. Most apps only want this in an admin panel. Don't put it in a shared provider that every panel (including customer-facing ones) boots — tracking tables are large and the resource queries are not free.
Gate access explicitly. The plugin registers Filament resources/pages; visibility should be enforced with policies or canViewAny()/canAccess() overrides, not just by hiding the nav item. A hidden nav entry is not authorization.
Extend rather than fork. The common pattern is to subclass the plugin's resource and swap it in, overriding getEloquentQuery(), table(), and getTableFilters():
class VisitsResource extends \NiekPh\VisitorTrackingFilament\Resources\VisitResource
{
public static function getEloquentQuery(): Builder
{
return parent::getEloquentQuery()->where('is_bot', false);
}
}
Same idea for widgets — register your own via the plugin's widget method so dashboard cards show your metrics (e.g. visits to /pricing that converted) instead of raw totals.
Default to a bounded time window. Set a default table filter of "last 7 days" and a sane defaultPaginationPageOption. An unfiltered SELECT * FROM visits ORDER BY created_at DESC on a table with millions of rows is the number one way this package makes a panel feel broken.
Tenancy. If you use Filament's tenancy, verify the resource query is actually scoped — either the plugin supports it or you scope it in your subclass. Leaking one tenant's visitor data into another's panel is a real and easy mistake here.
Data hygiene as a scheduled job. These tables grow monotonically. Wire pruning into the scheduler (the base package's model pruner or your own command), and add composite indexes on (created_at) and whatever you filter by (URL, user_id) if you filter on them heavily.
Tests. Disable the tracking middleware in phpunit.xml (or via config) so tests don't write visit rows, and use RefreshDatabase with the base package's migrations loaded. If you render the Filament page in a test, seed a handful of visit records via factories rather than hitting real tracking.
Deployment. After every upgrade, re-run php artisan filament:upgrade (or filament:optimize / filament:cache-components in CI) and check whether you've published views you now need to re-publish.
v1.0.7...v1.0.8 compare link. There is nothing in it indicating breaking changes, new features, or deprecations, so treat it as a low-risk patch, but read the diff before bumping rather than assuming. Pin ^1.0 and upgrade deliberately; a patch bump that silently touches a published Blade view is the usual surprise.vendor:publish --force on this package's views/assets will blow away customisations. Publish once, then track diffs manually or vendor the view.filament:clear-cached-components, not a registration bug.app.timezone. Either set ->timezone() on datetime columns or convert explicitly, otherwise "visits today" is wrong for several hours a day.pollingInterval on any live widget at 30s or more, and avoid ->deferLoading(false) on the visits table.Visit model with extra relations (e.g. linking visits to your User).How can I help you explore Laravel packages today?