jeffersongoncalves/filament-page-visits
A Filament plugin for tracking and displaying page visits in your admin panel. Log page views, see which pages are most popular, and review visit analytics without leaving Filament. Simple to install and configure for any Laravel app using Filament.
This release (3.2.0) adds a ResponseTimeTrendChart widget to the metrics page, so the fastest path to value is: install, get the underlying data flowing, then look at the chart.
Install / upgrade the data source first. The widget reads the response_time_stats column introduced in jeffersongoncalves/laravel-page-visits 1.3.0. Without it, the widget silently disappears.
composer update jeffersongoncalves/laravel-page-visits
php artisan vendor:publish --tag="page-visits-migrations"
php artisan migrate
Run the aggregator once by hand so you have something to look at before wiring up the scheduler:
php artisan page-visits:aggregate-and-prune
Register the plugin on your Filament panel (panel provider ->plugin(...)) if you haven't already, then open the metrics page in the browser. The response time trend renders as a 90-day p50/p95/p99 line chart in milliseconds.
Where to look first when something is off:
config/...metrics_page.php (or the published package config) → metrics_page.widgets.response_time_trendpage-visits migration stub to confirm the response_time_stats column existsFirst use case: "are we getting slower this quarter?" — open the metrics page, read p95 rather than p50, and correlate spikes with deploys. p50 tells you the typical request is fine; p95/p99 is where users complain.
Schedule the aggregator, don't run it ad hoc. The chart is only as fresh as the last aggregation. In routes/console.php (Laravel 11+) or the kernel:
Schedule::command('page-visits:aggregate-and-prune')->dailyAt('02:15');
Run it before any daily report or dashboard snapshot job, otherwise the chart lags a day.
Toggle the widget per environment. Because the widget is config-driven, use it as a feature flag rather than commenting out code:
// config/...metrics_page.php
'widgets' => [
'response_time_trend' => env('METRICS_RESPONSE_TIME_TREND', true),
],
This is the documented escape hatch and the cleanest way to keep the widget off staging panels where the column hasn't been migrated yet.
Order of operations for upgrades. The upgrade is genuinely three steps and the order matters:
composer update (gets you the new widget and the new column definition)vendor:publish --tag="page-visits-migrations" + migrate (creates the column)page-visits:aggregate-and-prune (fills it)If you skip step 3, the column exists but is null, and you'll spend time wondering why the chart is flat.
Pair it with the existing page-visits widgets. The natural workflow is: page-visits volume chart to find when traffic changed, response time trend to find whether that traffic correlated with latency. Put them adjacent on the metrics page; the two widgets share the same 90-day window, which makes the comparison honest.
Locale coverage is now a solved problem. With 19 locales translated, you generally should not publish the lang files. Only publish if you need to override copy — and if you do, treat it as a fork you must re-diff on every release.
Testing. A cheap regression test is to assert the widget's visibility matches the schema, so a future column rename doesn't silently blank the page:
$this->assertTrue(Schema::hasColumn('page_visits', 'response_time_stats'));
Then a Livewire/Filament test asserting the metrics page renders without errors.
Silent auto-hide is the number one trap. When the column is missing, the widget doesn't error — it just isn't there. A developer upgrading the plugin but forgetting the page-visits migration will conclude the feature "doesn't work." Check the column before you check the code.
Prune window vs. chart window. The chart advertises 90 days, but aggregate-and-prune also prunes. If your retention config is shorter than 90 days, the trend will be quietly truncated. Align the retention setting with the window you expect to see, or accept that the left edge of the chart is a lie.
No backfill. Percentiles are computed from data captured after the column existed. Days before you migrated 1.3.0 will have no response-time data — the chart will start at your migration date, not 90 days ago. Don't debug a "gap" that is really a deployment date.
Config cache. Toggling metrics_page.widgets.response_time_trend in production does nothing until php artisan config:cache (or config:clear in dev). This bites people who flip the flag during an incident.
Percentile semantics. p50/p95/p99 are computed over daily aggregates, not raw requests. A p99 on a low-traffic day can swing wildly on a handful of requests — read spikes alongside the request count before drawing conclusions or paging anyone.
Published translations go stale. If you've published lang files from an earlier version, the new widget's strings may fall back to keys instead of the 19 shipped translations. Either re-publish and merge, or stop publishing.
Extension points. For anything beyond the config toggle, subclass the widget and override its view rather than editing vendor files — the metrics page is a Filament page, so you can also swap the whole widget list in a custom page subclass if you need different layout or polling behaviour.
How can I help you explore Laravel packages today?