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 Client Laravel Package

simplestats-io/laravel-client

A lightweight Laravel client for Simple Stats, the privacy-friendly, cookie-free analytics platform. Track pageviews and custom events from your app using a clean API, Blade directives, and middleware, with GDPR-friendly defaults, simple configuration, and no complex setup required.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Verdict: update warranted. v5.1.0 is a minor version bump but introduces (a) a meaningful new capability that changes where data comes from, (b) a new public HTTP surface on the host application, and (c) a de facto breaking change for anyone subclassing the tracking middleware. All three are worth recording before rollout.

Architecture fit

  • The package is additive by design: a middleware plus a route/config block, no persistence, no queue, no new infrastructure. The beacon continues that pattern — it is a route plus a client snippet, not a new subsystem.
  • The beacon closes a genuine architectural blind spot. With Statamic "full measure" static caching, nginx/Varnish page caching, or Cloudflare "Cache Everything", PHP never executes for a page view, so the middleware is never invoked and those visits are simply absent from reporting. That is a data-correctness problem, not a feature gap, and it disproportionately affects exactly the audience this client targets (Statamic/high-traffic Laravel).
  • The design is sensible for the constraint: same-origin Referer carries the full URL and query string, so page path and utm_* are derived server-side without JavaScript; only external referrer needs document.referrer. The <noscript> pixel is a real fallback rather than decoration.
  • The package correctly states the preferred trade-off: where PHP still runs (Statamic "half measure", or any cache that revalidates through the app), no beacon is needed and fully server-side tracking remains better. The beacon is a fallback, not an upgrade.
  • Architectural concern: the feature re-introduces dynamic PHP execution into a request path that was deliberately made static. That is the central architectural consequence and needs to be treated as a capacity decision, not a config toggle.

Integration feasibility

  • Low effort for a standard Laravel/Statamic site: publish or hand-add the beacon block, add the layout snippet, choose the path, verify with the cache enabled. Off by default and inert without the config key, so the upgrade itself is a no-op.
  • Effort concentrates in environment-specific work: CDN exclusion rules for the beacon path, Referrer-Policy review, catch-all route precedence, WAF/bot-management allowlisting, and multi-domain/www vs apex handling (the design requires the pixel request to be same-origin with the page).
  • No database migrations, no data backfill, no schema coupling. Rollback is a config flag plus a template edit, though any visits collected only via the beacon during a trial will be lost from the series if rolled back.

Technical risk

  • Semver violation / subclass breakage (high, low likelihood). CheckTracking::getPage() and CheckTracking::doTracking() gained an optional parameter. Optional parameters are not compatible with overrides that omit them — PHP fatals with an incompatible declaration. It fails loudly at boot rather than silently, which is the better failure mode, but it is a hard error shipped in a minor. Any project that subclasses the middleware, or wraps it in a shared internal package, must audit before upgrading. Worth raising with the vendor: a new method, a variadic, or a major bump would have been safer.
  • New unauthenticated public endpoint (medium). A GET route that accepts arbitrary query parameters, performs bot filtering, hashing, and forwards to a third-party API. Mitigations in this release are bot filtering and dropping foreign-referer requests, but neither is a rate limit. The Referer header is client-controlled, so the foreign-domain check reduces accidental inflation from scraped or mirrored HTML, not deliberate abuse. Confirm what throttling exists and whether the endpoint can be scripted to burn API quota.
  • Data integrity assumptions (medium). Dedup between a cache-miss app response and the beacon of the same page is claimed; it needs verification under real conditions — back/forward-cache restores, prerender/Speculation Rules prefetch, retried fetch calls, and sites that leave the snippet on pages PHP also serves. Silent double counting or silent undercounting both corrupt trendlines without raising an error.
  • Silent no-data failure modes (medium). The route registers only if the config key exists, only in the first group listed in middleware_groups, and can be swallowed by a catch-all route, blocked by ad-blocker path heuristics, blocked by a WAF, cached by the CDN, or stripped by Referrer-Policy. Every one of these degrades to "fewer or zero visits," which looks like a traffic drop rather than a bug.
  • Path selection is an arms race (low/medium). The vendor explicitly recommends a path that avoids track, stats, analytics, beacon, collect, pixel, and avoids file extensions so the CDN does not cache it. The default assets/v is a deliberate evasion of blocklists and will need revisiting if list maintainers catch up. Budget for re-testing after blocklist updates.
  • Privacy posture (low). Hashing and bot filtering are stated to apply identically to beacon requests, and no cookies are introduced, so the model is unchanged. Still worth confirming with whoever owns privacy documentation that a client-initiated pixel does not alter the disclosed data flows.

Key questions

  1. Does the beacon handler respond independently of the upstream SimpleStats API call (respond-then-send / terminable middleware), or does it block on the API? A blocking handler turns a vendor outage into a latency and capacity incident on every page view.
  2. What cache headers does the pixel response send, and is the path excluded from CDN caching by default or only by documentation?
  3. What rate limiting, if any, protects the endpoint, and is there a per-IP or per-visitor cap?
  4. How exactly is dedup keyed and over what window, and does it hold when the snippet is left enabled on PHP-served pages?
  5. Does route registration survive route:cache, and does it take precedence over a catch-all route in the supported configurations?
  6. Which Referrer-Policy values are known-good and known-bad, and what is the observable symptom when it is misconfigured (missing page path only, or no visit at all)?
  7. Why was a required-signature change to two public methods shipped in a minor rather than a major, and is there an intended deprecation/support policy for subclassers?
  8. Is there a recommended pattern for multi-domain or www/apex sites where "same origin" is not a single value?
  9. What is the expected effect on reported totals when a site migrates from "no tracking on cached pages" to beacon-enabled — a step change that should be annotated on dashboards?

Integration Approach

Stack fit

  • Laravel-first package; no assumptions beyond the framework's middleware, routing, config, and env(). Fits Laravel 9–12-era projects and Statamic add-on installs without an adapter layer.
  • Complements rather than replaces existing cache strategy. The correct decision order is: (1) can the site use a cache strategy that still executes PHP (half measure)? If yes, stop — server-side tracking is strictly better. (2) Only if PHP is fully bypassed, enable the beacon.
  • The client snippet is plain ES5-compatible JavaScript plus a <noscript> image; no build step, no framework coupling, safe to drop into an Antlers/Blade layout or a shared partial.

Migration path

  • Upgrade the Composer constraint to ^5.1. The release is inert until the config block and template snippet are added, so the code upgrade and the feature enablement can be separate deploys — use that.
  • Two config paths: hand-add the beacon block to the published config/simplestats-client.php, or republish. Prefer hand-editing or a documented diff; vendor:publish --force overwrites local customisations. Then php artisan config:clear / config:cache on deploy.
  • Keep the beacon behind SIMPLESTATS_BEACON_ENABLED per environment so staging can be validated against production-like caching.
  • For subclassers: patch method signatures to match the new optional parameter before upgrading, or pin to 5.0.x until the override is retired. Add a boot/smoke test that boots the app so an incompatible declaration is caught in CI rather than at deploy.

Compatibility

  • Existing installs with an older published config are expressly unaffected — no key, no route. This is the right default and the main reason this release is low-risk to adopt.
  • Statamic "half measure" and any revalidating cache: no change, do not enable the beacon.
  • Full-measure static cache, nginx/Varnish page cache, Cloudflare Cache Everything: this is the target case; requires CDN exclusion for the beacon path, route-precedence verification, and Referrer-Policy review.
  • Known interaction hazards: navigator.sendBeacon is explicitly unsupported (POST-only), so the provided fetch(..., { keepalive: true }) pattern must be used verbatim; ad-blocker heuristics on path naming; WAF/bot-management scoring of cookie-less image requests; catch-all routes shadowing the endpoint.
  • Behavioural change: tracking codes are now restricted to scalar values. Prevents ?utm_source[]=x style payloads from being rejected upstream. Low compatibility risk, but it is a validation change and belongs in release notes for anyone constructing those parameters programmatically.

Sequencing

  1. Audit — search the codebase (and internal shared packages) for subclasses or overrides of CheckTracking; search for existing server-side tracking assumptions on cached pages.
  2. Upgrade inert — bump to ^5.1, clear/rebuild config and route caches, deploy with the beacon off. Verify no route or boot regressions.
  3. Enable in staging — add the config block and snippet, exercise the real cache path (confirm PHP is bypassed), verify a visit appears with correct page path and utm_* values, verify the <noscript> path separately by disabling JS.
  4. Validate counting invariants — confirm a cache miss served by the app plus its beacon counts once; confirm the pixel is not CDN-cached; confirm the path is not blocked by the CDN, WAF, or a representative set of ad blockers.
  5. Capacity check — size the added PHP request rate before production enablement (see Scaling below).
  6. Canary — enable on one site or one low-traffic segment, watch request volume, error rate, and API error responses for a defined window.
  7. Production enablement + annotation — enable, and annotate dashboards and any client-facing reports with the date the counting method changed.
  8. Follow-up — re-check the beacon path against blocklists on a schedule, and revisit once the vendor signals a path change or a deprecation.

Operational Impact

Maintenance

  • Low steady-state code maintenance; the package is a thin client and the addition is a route plus a snippet.
  • Non-zero configuration maintenance: the beacon path is a soft evasion of blocklists and should be reviewed periodically; CDN, WAF, and Referrer-Policy settings that made the beacon work are now load-bearing and must not be changed casually by other teams.
  • Upgrade risk for the next several releases is concentrated in the middleware signatures, not the beacon. Treat the middleware's public methods as an extension point the vendor may keep evolving.

Support

  • Expect inbound "our traffic dropped" tickets that are actually beacon suppression: ad blocker, WAF, CDN caching the pixel, missing Referrer-Policy, catch-all route precedence, or a config block that never made it into the deployed config. Publish a short triage runbook mapping symptom → cause → check.
  • Expect "why do the numbers differ from the old system" questions. The answer is that the old numbers were missing cached traffic entirely; this release makes them more correct, which looks like growth. Pre-brief stakeholders and annotate reporting before enablement, not after.
  • Snippet ownership matters: it lives in templates, so it can be dropped by a theme change or a marketing tool's layout override without any deploy signal. Add it to template-level smoke checks if available.

Scaling

  • This is the most significant operational consequence of the release. Sites in the target scenario were previously serving 100% of page views from cache with effectively zero PHP execution. Enabling the beacon means one PHP request per page view. On a high-traffic site that is not a marginal increase — it can be orders of magnitude more dynamic requests than the origin handled before, and it lands on a PHP-FPM pool that was sized for a cached site.
  • Plan for it explicitly: size PHP-FPM workers and opcache for the new request volume, keep the beacon handler minimal (no framework-heavy work, no synchronous outbound call), exclude the beacon path from APM sampling and from log pipelines that will otherwise be flooded, and ensure it is excluded from the CDN cache but included in whatever rate limiting you run.
  • Conversely, if the site already serves most views through PHP (half measure, or a cache miss ratio that is not near zero), the beacon adds one extra HTTPS request per view for little benefit — another reason to gate feature-by-feature rather than enabling everywhere.
  • Upstream API call volume shifts from middleware invocations to beacon requests; overall volume should be comparable or higher, so verify quota and rate-limit headroom with the vendor if the site has significant cached traffic.

Failure modes

  • Subclass signature mismatch — PHP fatal on boot. Loud, immediate, caught by any boot smoke test; catastrophic only if it reaches production without one.
  • Blocking beacon handler — if the pixel waits on the SimpleStats API, a vendor slowdown consumes PHP workers on every page view and can cascade into an availability incident on the origin. Verify the response does not depend on the upstream call completing.
  • Silent undercount — ad blocker, WAF/bot management, CDN caching the pixel, Referrer-Policy: no-referrer, catch-all route shadowing, stale route:cache, or a config block missing from a deployed environment. None raise errors; all present as a traffic decline.
  • Double count — snippet left enabled on pages that PHP also tracks, or dedup defeated by prerender/bfcache/retries. Presents as a traffic spike and a divergence between page-view and unique-visitor ratios.
  • Spoofed referer — the foreign-domain drop is a filter against mirrored HTML, not an anti-fraud control. Anyone can set Referer; do not treat these numbers as adversarially robust.
  • Path collision — the configured path overlaps an existing route or a static asset; depending on precedence the pixel 404s or a real asset is shadowed. Choose the path deliberately and verify precedence.
  • Data discontinuity — a step change in reported visits at enablement. Harmless analytically if annotated; misleading if not.

Ramp-up

  • Standard Laravel/Statamic site, single domain, CDN already in use, no middleware subclass: roughly half a day of engineering to upgrade, configure, deploy, and verify, plus a monitoring window of a few days on a canary.
  • Site with middleware subclasses, multi-domain or www/apex routing, a strict Referrer-Policy, an aggressive WAF/bot-management tier, or a strict change-approval process for CDN rules: 2–3 days of engineering plus cross-team coordination with whoever owns CDN/WAF/security, and a longer validation window.
  • Add explicit time for the capacity review — it is easy to overlook because the code change is trivial, and it is the item most likely to cause an incident.
  • Prerequisite knowledge: how the site's caching actually works (full measure vs half measure vs CDN page cache), where the CDN and WAF rules live, and who can change Referrer-Policy. If nobody on the team can answer those, that gap is the real ramp-up cost.
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.
adachsoft/changelog-linter
adachsoft/collection
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast