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

spatie/laravel-analytics

Retrieve data from Google Analytics in your Laravel app with spatie/laravel-analytics. Simple methods like fetchMostVisitedPages and fetchVisitorsAndPageViews return Laravel collections, with easy Composer installation and publishable config.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit

spatie/laravel-analytics is a thin, read-through adapter over the Google Analytics 4 Data API, exposed as a Laravel facade (Spatie\Analytics\Facades\Analytics) returning Illuminate\Support\Collection instances. It is deliberately not an ETL tool, a warehouse loader, or a metrics store — it holds no state beyond an optional cache.

That makes the fit decision binary and easy to reason about:

  • Strong fit when the product requirement is "surface a handful of GA4 metrics inside our Laravel app" — admin dashboards, client portals, marketing widgets, Filament/Nova panels, report PDFs, internal ops screens.
  • Weak fit when the requirement is "build our analytics capability." Anything needing event-level granularity, historical depth beyond GA4 retention, joins against transactional data, or sub-daily freshness belongs in the GA4 → BigQuery export path, with this package at most as a convenience layer.

A TPM should frame this as a buy-vs-build on ~500 lines of glue code: the package replaces a google/analytics-data client wrapper plus credential/config plumbing. The value is not capability, it's compression of undifferentiated work.

Integration feasibility

The path is well-trodden and fully documented: Composer install → publish config/analytics.php → create a GCP project → enable the Analytics Data API → generate a service-account JSON key → grant that service-account email Viewer/Analyst on the GA4 property → set ANALYTICS_PROPERTY_ID.

Realistic estimates: half a day for a spike, plus 1–2 days of coordination with whoever administers the GA4 property (this is usually a marketing or agency third party, and is the most common schedule slip). The Analytics::fake() helper is a genuine accelerant — it means CI has no dependency on live Google credentials, which is where comparable packages often fail.

Technical risk

  1. Vendor type leakage. The escape-hatch get() method requires callers to construct Google\Analytics\Data\V1beta\FilterExpression, OrderBy, StringFilter objects directly. That couples application code to a beta Google protobuf namespace. This is the single largest long-term risk and must be contained behind an app-level wrapper.
  2. Secret handling. The default config points at storage_path('app/analytics/service-account-credentials.json'). In a containerised or multi-environment deployment this needs to move to an env-supplied array sourced from a secret manager, with defined rotation. A long-lived JSON key with property read access is a standing credential.
  3. Single global property. property_id is read from config. Multi-brand, multi-tenant, or agency-per-client products need a per-call override or a service wrapper that manages property context — this is not solved out of the box.
  4. Staleness vs. quota is the central trade-off. Default cache is 24h (cache_lifetime_in_minutes). Too long and dashboards mislead; too short and you burn GA4 quota and request latency. This is a product decision, not a config detail.
  5. Silent data quality loss. GA4 applies thresholding and sampling. Results can be incomplete without erroring — the most dangerous failure mode for a dashboard people make decisions from.
  6. Ecosystem signal is mixed. 3.2k stars and a healthy release/changelog cadence from Spatie are strong signals; the reported 0 dependents and low opportunity score are almost certainly undercounted (Packagist download volume is the better proxy). Treat the dependents figure as a data-quality caveat, not a maturity verdict.

Key questions

  • Which specific reports and which decisions do they drive? (Determines whether this package is sufficient or BigQuery export is mandatory.)
  • Who owns the GA4 property and the GCP project, and can we get service-account access this quarter?
  • Single property or N properties? Multi-tenant?
  • What is the acceptable data freshness — real-time, hourly, daily?
  • Do we need history older than GA4's 14-month retention window? If yes, we need persistence or BigQuery.
  • Is GA4 the system of record for these numbers, or must they reconcile with internal event data?
  • Which Laravel/PHP versions are in scope, and what is our dependency upgrade cadence for beta-namespaced Google libraries?

Integration Approach

Stack fit

Composer-native, Laravel-first, facade-based, Collections out. This drops cleanly into Blade views, Inertia props, API resources, and Livewire components without transformation. Credentials and caching reuse Laravel's existing config and cache infrastructure, so there is no new operational surface — the cache store is whichever store the app already runs.

The important constraint: treat the facade as an infrastructure boundary, not a domain API. The correct integration is a single AnalyticsService (or repository) in the app that owns property resolution, period construction, cache policy, retry, and mapping to app-owned DTOs. Every controller and view talks to that service. Nothing outside it imports Spatie\Analytics or Google\Analytics\Data\V1beta.

Migration path

  • From spatie/laravel-analytics v4 / Universal Analytics: this is the GA4 rewrite; the migration is not drop-in. Return keys changed (visitors → activeUsers, pageViews → screenPageViews, url → fullPageUrl), and method names shifted (fetchVisitorsAndPageViewsByDate, etc.). Budget 1–3 days for call-site and view changes even in a modest app, and grep aggressively for key names in Blade templates where breakage is silent rather than fatal.
  • From hand-rolled google/analytics-data client code: straightforward and a net reduction in code; port the query-building into the get() call or the DTO wrapper.
  • From analytics-php / Reporting API v4: UA-era, effectively a rewrite.

Compatibility

Pin the package and google/analytics-data explicitly. The V1beta namespace is the churn vector — expect a V1 promotion and watch the changelog for it. Confirm Laravel and PHP version support against the package's composer.json before committing; Spatie drops older Laravel majors on a predictable cadence.

Sequencing

  1. Spike (1 day): real GA4 property, one dashboard page, verify the numbers against the GA4 UI. Validate before building anything — mismatched numbers are the classic late-stage discovery.
  2. Credentials and config (1–2 days): service account, property access grant, secret-manager-backed credentials, config cache verified across all environments, documented rotation runbook.
  3. Wrapper layer (2–4 days): AnalyticsService with property context, DTO mapping, cache policy, retry/backoff, and graceful degradation. Tests use Analytics::fake().
  4. Feature delivery: dashboards, exports, scheduled reports.
  5. Contingency, deferred: if retention or granularity requirements surface, add a scheduled snapshot job into app-owned tables, or move to BigQuery export with this package retained for live "last 7 days" panels.

Operational Impact

Maintenance

Small code footprint, MIT licence, active Spatie ownership with a maintained changelog and release train. Ongoing effort is low but non-zero: the real maintenance driver is the transitive google/analytics-data dependency, not this package. Plan a quarterly dependency review and expect one meaningful upgrade event when the beta namespace stabilises. Total cost of ownership is dominated by secrets management and dashboard correctness, not by code upkeep.

Support

Community-only, no SLA, no vendor escalation. The support path is GitHub issues plus internal Laravel expertise. Name a backend owner for the integration and a product/marketing owner for the GA4 property relationship — most incidents are caused by changes on the GA4 side, and without a named counterpart you will debug blind.

Scaling

The system is quota-bound, not compute-bound. Google enforces per-property token quotas; the package's response cache is the primary lever, and the cache TTL is effectively your capacity plan.

  • Never issue live API calls inside a user-facing request for anything but the cheapest query.
  • For pages with several metrics, use a scheduled prefetch job writing to Redis or app tables; serve requests from cache.
  • Long periods and high-cardinality dimensions are the expensive calls — cap maxResults, restrict dimension sets, and prefer Period::days(7/28) presets over arbitrary ranges.
  • Watch GA4 property access at scale: an agency pattern with per-client properties multiplies both quota and credential surface.

Failure modes

Failure Symptom Mitigation
Service-account key expired/revoked 401/403, hard failure Rotation runbook; alert on auth errors; keep key in secret manager
Property access removed or role downgraded 403 on all calls Contractual/process check with property owner
Analytics Data API disabled in GCP project 403 with opaque message Pin in infra-as-code and monitor
Quota exceeded 429 Serve last-known-good cached payload; exponential backoff; alert at 80%
GA4 thresholding/sampling Numbers silently wrong, no error Surface a data-quality disclaimer; spot-check against GA4 UI; consider BigQuery export
Cached config after property change Wrong property's data displayed Config-cache clear in deploy pipeline; assert property ID at boot
Network timeout in request path Page error Move to queue/prefetch; timeout + empty state
Silent key-name change on upgrade Blank values in views, no exception Typed DTO mapping with explicit key assertions; smoke test in CI

Design for graceful degradation from day one: every analytics surface should have a cached-last-known-good path and an empty-state UI. An analytics widget that errors the page is worse than one that says "data temporarily unavailable."

Ramp-up

Low for any Laravel developer — hours to first successful call. The genuine learning curve is GA4 Data API semantics (dimension/metric compatibility rules, ordering, keepEmptyRows, filter expressions), which is Google's complexity, not the package's. Budget roughly a week for one developer to go from zero to confidently shipping production dashboards, including the credential and quota work.

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.
abuseio/abuseio
seophp/robots-laravel
seophp/head-laravel
bladeknigt89/yii2-dd
gesflow/sender-laravel
apxcde/laravel-telltale
smswire/smswire-php
ulsyairil/transactional-outbox
wyox/laravel-gitlab-reporter
amprest/laravel-datatables
itashia/laravel-jalali
carlosocarvalho/elasticsearch
rwsite/wp-field
voorhof/stickler-light
e-nikitin/laravel-bigquery
codewithathis/paperless-ngx
wika-group/sessionservice-for-laravel
clikgate/clikgate-laravel
waqas-badar/laravel-saga
aporat/laravel-cloudwatch-logger