Product Decisions This Supports
- Build vs. buy for first-party visitor tracking. The package collapses a 1–2 sprint build (user-agent parsing, visit log schema, polymorphic relations, online detection, middleware) into a
composer require plus a migration. That makes it a viable "buy" answer when the roadmap item is "show view counts / who's online" rather than "become an analytics company."
- Feature grooming for engagement surfaces. It directly unlocks a specific, demo-able feature class: "X people are viewing this," "trending content," per-model view counts, recently-viewed lists, and admin "active users" panels. PMs can scope these as small, shippable increments rather than platform bets.
- Personalization and merchandising roadmaps. Browser/device/platform/language metadata at request time is enough to justify device-aware layouts, locale defaults, or campaign routing — without standing up a CDP.
- Content and marketplace ranking inputs.
visitLogs() counts and IP-deduplicated unique counts give a cheap popularity signal for sort orders, "most viewed" modules, and seller/buyer activity scoring. Decide now whether view counts are a product-facing metric (they become a contract once shown in UI).
- Trust & safety / support triage. IP + user-agent history per user and per model is a low-cost audit trail for abuse investigation and support ("what did this user actually see?"). This is often the unglamorous justification that gets it funded.
- Compliance-driven roadmap decisions. Built-in route exclusions and password-field stripping (since v2.2) mean the "do we need a DPA / consent banner for this?" conversation has a concrete answer: server-side, first-party, no third-party pixel. That can defer or shrink a privacy workstream.
- GeoIP as a scoped experiment, not a commitment. GeoIP enrichment is optional and additive (v4.5.0). PMs can fund it as a single follow-up ticket if city/region granularity proves valuable, instead of buying a geo vendor on day one.
- Build-vs-buy comparison baseline. Worth evaluating against: PostHog/Plausible/Matomo (full analytics, client-side, external dependency), Laravel's own
Request::ip()/userAgent() plus a hand-rolled table (full control, no maintenance risk), or a queue-based event pipeline if volume is high. This package wins on time-to-market for Laravel-native, server-side, model-scoped tracking and loses on depth, scale, and bus factor.
Key PM caution: the repo shows 0 dependents and a single-maintainer profile. Treat it as a thin, replaceable dependency — wrap it behind your own VisitTracker interface so swapping it later is a config change, not a refactor. That architectural decision is the PM's to insist on, and it's what de-risks the whole adoption.
When to Consider This Package
Adopt when:
- You're a Laravel 5.5+ (through 13.x) monolith and the requirement is literally "track visits to our models" or "show who's online."
- The value is in model-scoped, polymorphic visit logs with
Visitable/Visitor traits — i.e., you want $post->visitLogs()->count() and $user->isOnline() and nothing more.
- You want server-side only tracking: no JS snippet, no cookie consent dependency, resistant to ad blockers.
- You need online-user presence without spinning up WebSockets/Pusher/Redis pub-sub.
- You're pre-product-market-fit or in an internal tool, where a 568-star package with recent Laravel compatibility patches is an acceptable risk and "two weeks saved" beats "zero dependencies."
- You have engineering capacity to own the integration: route exclusions, IP anonymization/hashing, retention policy, and indexes on the visit table.
Look elsewhere / build it yourself when:
- Analytics depth matters. No funnels, retention, session replay, attribution, or cohorting. If the roadmap says "understand the funnel," use PostHog, Mixpanel, or a warehouse — not this.
- Scale is real. Every
visit() is a synchronous DB write. At high traffic this becomes a write hot spot and a table that grows unbounded. Above roughly a few million visits/month, plan for queueing, partitioning, or a dedicated pipeline — at which point a purpose-built solution is cheaper than bending this one.
- The visit log becomes business-critical. 0 dependents and one maintainer means abandonment risk. If revenue depends on the metric, internalize the code (MIT — fork it) or build it.
- You need PII/regulatory rigor beyond GDPR baseline. No built-in IP anonymization, retention jobs, or encryption. HIPAA-adjacent or regulated environments require custom work that erases the time savings.
- Non-Laravel services or multi-language stacks are in scope — this is Laravel-only glue.
- You need precise geo. Optional GeoIP is a convenience, not a substitute for MaxMind/IP2Location if region/city accuracy is a product requirement.
- You want rich custom visitor attributes (CRM tier, loyalty status, account plan) joined into tracking — you'll be writing that schema yourself anyway.
Decision heuristic: if the ticket reads "show a view counter and an online badge," this package is a clear yes with a wrapper interface. If it reads "build our analytics capability," this package is the wrong tool and shouldn't be in the doc.
How to Pitch It (Stakeholders)
One-liner: A small, Laravel-native library that gives us visitor metadata and per-model visit tracking — so we can ship "who's viewing this" and "trending" features in days, not sprints, with no third-party analytics vendor and no client-side tracking.
For executives — the business case:
- Speed to a visible feature. This is the cheapest credible path to engagement surfaces users notice: view counts, trending modules, "X people viewing now," and admin active-user dashboards. Estimated effort drops from a sprint-plus to a few days of integration.
- No new vendor, no new data-sharing surface. Purely first-party and server-side. Nothing leaves our infrastructure, no cookie banner work is triggered, no contract or DPA to negotiate. That's a procurement and legal win as much as an engineering one.
- Cheap experiment, cheap exit. MIT-licensed, thin surface area, easily isolated behind our own interface. If it doesn't earn its keep, removal is a config change — not a migration project.
- Honest risk framing: it's a small open-source project with a single primary maintainer and few known dependents. Mitigation is architectural, not contractual: we wrap it, we own the schema, and we can fork it. That's why we're scoping it to engagement features, not to business-critical analytics.
For engineering — what we're actually asking for:
- Adopt as an implementation detail, not a platform. Introduce a
VisitTracker interface in our domain layer; the package sits behind it. That single constraint removes the abandonment risk from the conversation.
- Scope of use:
$request->visitor() for browser/platform/device/language/IP; Visitable on the models where view counts are a product requirement (start with 2–3, not all); LogVisits middleware only on public read routes, with wildcard exclusions for auth, checkout, and admin paths.
- Non-negotiables before merge: exclude sensitive routes, confirm password fields are stripped, hash or truncate IPs per our privacy stance, add a scheduled retention/prune job, and index the visit table on
(visitable_type, visitable_id, created_at) and on ip for dedup counts.
- Watch item: synchronous writes on every tracked request. Start synchronous; add queueing when we see it in profiling. Don't pre-optimize, but instrument it.
- What we're explicitly not doing with it: funnels, retention curves, attribution, or session replay. Those stay out of scope, which keeps this dependency small and disposable.
Ask: approve a timeboxed spike (2–3 days) to wire the wrapper, migrations, and one visible feature; ship behind a flag; measure query load and table growth for two weeks before committing to broader rollout.