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

Laravel First Party Analytics Laravel Package

amjadiqbal/laravel-first-party-analytics

First-party analytics for Laravel: collect and store visitor and event data on your own infrastructure without third-party scripts, giving you privacy-friendly, self-hosted reporting and insights.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. This is an in-process analytics collector: a middleware on the web group writes pageviews and visits into the host application's own database, with a Blade dashboard for reading them back. It fits the common case well — a Laravel 12/13 monolith that wants basic traffic, referrer, UTM, conversion and funnel reporting without shipping request data to Google or standing up a separate Plausible/Fathom/Umami service. It is explicitly not a product-analytics tool: no cohorts, retention curves, session replay, experiments, or user-level exploration mentioned. Scoping expectations accordingly is the single most important framing decision.

The fit weakens in three cases worth naming up front: multi-tenant SaaS (nothing in the notes indicates tenant scoping on the stored rows or the dashboard queries), API-only/headless backends (tracking is bound to successful HTML responses on web), and any deployment with full-page caching or a CDN serving cached HTML — the middleware never runs on a cache hit, so traffic would be silently undercounted by whatever fraction is served from cache.

Integration feasibility. Low friction: composer require plus php artisan migrate, and tracking is automatic via the web group. That "automatic" is also the main integration hazard — the package mutates a framework middleware group, so it must be verified against existing middleware ordering, tenancy resolution, and TrustProxies configuration. Everything else (Blade directive, facade, artisan commands, config-driven funnels) is conventional Laravel surface area.

Technical risk.

  • Pre-1.0 dependency in the request path. v0.1.0 carries no backwards-compatibility promise. Schema and config keys can change in 0.2 and 0.3; Composer will resolve ^0.1 narrowly, so minor bumps are effectively deliberate upgrade events. Budget for migration review on every bump, and pin exactly for the first months.
  • Privacy posture is better than most, but "no-cookie" is not "no personal data." A daily-salted hash of IP + user agent + host is pseudonymous data; under GDPR/ePrivacy it is still very likely personal data. That is fine, but it needs a legal basis, privacy-policy text, and a documented retention window — none of which the package can supply. Analytics::identify() and the Login/Registered user linking deliberately change the posture by joining behaviour to an identified person; that path deserves separate review and probably consent.
  • CDN-header country is trust-sensitive. Country is read from a CDN header, which is only meaningful behind a trusted proxy. If TrustProxies is misconfigured or the app is reachable directly, clients can spoof it.
  • Consent and opt-out surface. DNT and GPC are respected, plus Analytics::ignoreUsing(). Good defaults — but they create a permanent gap between this tool's numbers and any tool that ignores those signals, which will surface as "why don't the numbers match?"
  • Coverage gaps that show as undercounting. Livewire updates are skipped, so Livewire navigate-style navigation will not register pageviews. Prefetches skipped is correct; SPA-style transitions not counted is a real reporting limitation, not a bug.
  • Untested paths. Queue write mode was unit-tested (job dispatched and applied) but not against a real queue worker; the browser test ran on SQLite while MySQL/Postgres were covered only by integration runs. Both are cheap to validate and should be validated before production.
  • Single-maintainer, single-release. No stated support policy, security policy, or 1.0 timeline. Treat it as a dependency you may need to fork.

Key questions. Is there tenant scoping on stored rows and dashboard queries? Is a separate DB connection supported, and is the schema indexed for the dashboard's range queries? What is the intended path and timeline to 1.0? Who is expected to define the dashboard gate in production (local-only default is a safe default, not a policy)? Does the browser snippet work under a strict CSP (inline script, nonce, connect-src)? What fraction of production HTML is served from cache? Is there an export path before analytics:prune deletes data?

Integration Approach

Stack fit. Laravel 12 and 13, PHP 8.3–8.5, MySQL 8.4 / PostgreSQL 17 / SQLite — matches a current, well-maintained stack and shows the maintainer tracking Laravel's release cadence closely (Laravel 13 support at first tag). Non-fits: PHP 8.2 or older Laravel, Lumen/Symfony, and anything where the "web" group isn't the page-serving path.

Migration path. Purely additive: no changes to existing tables, no interception of existing flows, no data export required to start. The one-way door is the data itself — adopting means owning a growing pageviews/visits/events dataset inside your own database indefinitely. Decide retention (retention_days) before the first install rather than after the table has grown, and decide whether the data belongs in the app's primary database at all.

If this replaces GA4 or Plausible, run both in parallel for two to four weeks and reconcile before switching anything off. Expect this tool to report lower pageviews — DNT/GPC compliance, bot filtering, no-cookie visit stitching, skipped Livewire transitions, cache-served pages. Agree the acceptable delta with whoever consumes the numbers, or the first traffic review becomes a debate about instrumentation.

Compatibility. Pin the exact version in composer.json for now. Add the package to your Laravel upgrade checklist: a framework major should not ship before the analytics package supports it, and you do not want to be the one discovering that on upgrade day. Add a smoke test in your own suite that a tracked route writes a row.

Sequencing.

  1. Sandbox install; confirm middleware ordering composes with tenancy and auth middleware, and that the dashboard is inert by default.
  2. Privacy/legal review of no-cookie mode and the identify()/user-linking path; draft policy text and set retention_days.
  3. Staging with production-like traffic shape: exercise the queue write mode against a real worker, and confirm behaviour behind your CDN/cache.
  4. Define the viewFirstPartyAnalytics gate explicitly per environment — who sees it, behind what auth and network boundary.
  5. Canary on one route group; compare counts to the incumbent for a week.
  6. Full rollout, then wire analytics:prune into the scheduler and alerting.

Operational Impact

Maintenance. Low code footprint, small maintainer team (one), pre-1.0, no published support window or security-disclosure route. The engineering hygiene signals are strong for a 0.1 — 86 Pest tests across a PHP 8.3/8.4/8.5 × Laravel 12/13 matrix, PHPStan level 6, Pint, an install verified in a real app in a real browser. That reduces but does not remove the bus-factor risk. Assume you may need to carry a patch; keep the fork path open by not building app logic on top of the package's internals, only on the facade and the documented config.

Support. Community-only, no SLA. Name an internal owner for the three recurring questions: who reads the dashboard, who tunes retention, and who investigates "traffic looks wrong." Without that, the first anomaly becomes an unowned investigation. Note also that the numbers are now your numbers — there is no vendor to blame for a counting discrepancy.

Scaling. The write path is one pageview per HTML response, batched after the response by default. On the primary database that is write amplification competing with transactional traffic; at meaningful volume, use a separate connection and confirm the pageviews table is indexed for the dashboard's date-range and grouping queries. The prune command deletes in chunks, which is the right design, but its runtime grows with data — run it off-peak and monitor it. The browser event endpoint is public by design; same-origin checks and rate limiting are the right controls, but the rate limiter needs a shared cache store in a multi-node deployment or the effective limit multiplies by node count. Put the endpoint behind the same CDN/WAF as the rest of the app.

Failure modes.

  • Silent data loss. Write failures are reported, never thrown. That is the correct choice for analytics, but it means nobody notices unless someone watches the logs. Add an alert on the report path.
  • Queue mode holes. Untested on a real worker; a stalled or misconfigured worker produces gaps, not errors. Instrument job throughput if you enable it.
  • Cache-served pages. Zero tracking for any HTML served from a CDN or response cache — a partial outage that looks like a traffic drop.
  • Retention misconfiguration. Too high and the table grows unbounded on the app's primary database; too low or an aggressive --days run and you lose history you cannot reconstruct. --pretend exists; use it in the first manual runs.
  • Spoofed geo. Country from a CDN header is only trustworthy behind correct trusted-proxy configuration.
  • Endpoint abuse. Rate-limited and same-origin-checked, but still an unauthenticated write path into your database; watch it after launch.

Ramp-up. Low for a Laravel developer: facade, one Blade directive, one config file, two artisan commands — half a day to install and see data. Medium for the surrounding work, which is where the effort actually is: gate definition, retention policy, log alerting, privacy review of the identified-user path, and the parallel-run reconciliation. Plan one to two engineering days to productionize, plus legal/privacy review time, and treat the dashboard gate and retention window as launch blockers rather than follow-ups.

Overall. Worth a pilot, not yet a default. The architecture is right for a Laravel monolith that wants first-party, privacy-respecting traffic and conversion data without extra infrastructure, and the privacy defaults are unusually thoughtful. The blockers to a broader rollout are the pre-1.0 API, the single-maintainer support model, tenant scoping (if relevant to you), and the consent/retention decisions that only your organisation can make. Adopt behind a pinned version, with a named owner, an explicit retention policy, and a confirmed answer on caching and the queue worker.

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.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
cgv/localized-resource