Product Decisions This Supports
- Build vs. buy for internal reporting surfaces. If we already run a Filament admin panel, this package replaces a scoped "traffic overview" feature we would otherwise spec, design, and build. The decision it informs: do we spend engineering sprints on a bespoke GA integration, or ship a config-and-credentials integration and redirect that capacity to core roadmap work?
- Whether analytics belongs inside the product at all. The package makes a specific product bet cheap to test: that internal users (marketing, content, ops, customer success) will consume top-level traffic and engagement metrics in-context rather than tabbing over to GA. If the pilot shows nobody opens the dashboard, we've learned that for a few days of setup cost instead of a quarter of engineering.
- Scope of the "reporting" roadmap item. The v1.1.0 filters (date ranges/metrics) are the practical threshold between a demo widget and something stakeholders use weekly. That lets us decide whether reporting is "done" for the next release or needs a custom widget layer on top — and lets us distinguish a canned traffic page (buy/integrate) from bespoke reporting (build on
spatie/laravel-analytics directly, no fork).
- Where analytics should live. Because the plugin is registered per panel, the decision of which surfaces (internal admin, customer-facing, multi-tenant) get analytics becomes an explicit product choice rather than a default. The guidance here is to keep it in an internal, permissioned panel and resist dynamic per-tenant property mapping.
- Prioritizing self-serve over ad-hoc requests. Routine "how is this page doing / where is traffic coming from" questions currently route through engineering or a data team. This package is a lever to reduce that interrupt load — a measurable, PM-relevant outcome.
- Setting the boundary with product analytics. The package is a display layer over GA, not an event-tracking or BI system. It explicitly should not drive decisions requiring first-party event data, funnels, retention, or cohort analysis — those stay with a dedicated platform. Codifying that boundary prevents scope creep into a "let's just add funnels" request the architecture can't support.
When to Consider This Package
Adopt when:
- The application is on Laravel + Filament and the goal is analytics inside the existing admin UI, not a standalone tool.
- Google Analytics (GA4) is already the accepted source of truth, or we're willing to make it so, via a Google Cloud service account and the
spatie/laravel-analytics dependency.
- The requirement is a lightweight, read-only traffic overview — visitors, page views, top pages, referrers, date-range filters — for internal users.
- We can absorb single-maintainer risk: version pinning, changelog review before minor bumps, and a willingness to vendor or fork if the maintainer goes quiet. Last release was December 2022, so treat this as a frozen, small-surface dependency rather than an actively evolving one.
- We have — or can assign — someone to own the Google-side setup: service account, Analytics Data API enablement, numeric GA4 property ID, service-account Viewer access on the property, and cache store configuration. This is where the real effort is, not in the code.
- Operational hygiene is in place: a shared persistent cache (Redis/database, never
file on multi-node), plugin registration gated to production, and authorization so analytics isn't visible to every panel user.
Look elsewhere when:
- We are not on Filament, or need framework-agnostic reporting.
- We need event-level product analytics — funnels, retention, cohorts, experiments. Use a dedicated product-analytics platform; this package cannot and should not get there.
- We require SLAs, enterprise support, or a maintained release cadence. A 2022 last release and a thin contributor base mean the support contract is effectively "we own it."
- There are data-residency or privacy constraints that prohibit pulling data through Google Analytics.
- We need per-tenant / per-customer analytics isolation; the widget doesn't model this natively and dynamic property IDs get messy fast because one service account needs access to every property.
- We need near-real-time reporting — GA4 has a ~24–48h freshness lag, so "today so far" views will look stale by design.
How to Pitch It (Stakeholders)
For executives: This is a small, low-cost integration that surfaces Google Analytics traffic data inside our existing admin panel. Internal teams — marketing, content, ops — can check page and campaign performance without us building a custom dashboard and without leaving the product, which reduces ad-hoc reporting requests to engineering. The integration itself is mostly configuration; the real cost is a one-time Google credentials setup. v1.1.0 added date-range filtering and consolidated the underlying views, which improves day-to-day usefulness and lowers maintenance surface. The trade-offs are explicit: it depends on Google Analytics as the data source and on a single-maintainer community package last released in 2022. That makes it a good fit as an internal reporting convenience, and explicitly not a substitute for a strategic analytics platform. Recommendation: pilot it in an internal-only panel, pin the version, and treat it as a convenience layer — not a system of record.
For engineering: A Filament plugin wrapping spatie/laravel-analytics, rendering GA4 metrics as panel widgets and a page (visitors, page views, top pages, referrers). Integration is genuinely low-effort if we're already on Filament and have a GA4 service account configured — the plugin registration is a one-liner in the panel provider and config publishes cleanly. The work is on the Google side: enable the Analytics Data API, add the service-account email as a Viewer on the numeric GA4 property, and point config at a storage_path() credentials file (relative paths break under queue workers, Octane, and differing deploy roots). Non-negotiables for production: a shared persistent cache store with a sensible TTL (per-filter-state cache keys fan out, so ~24h), plugin registration gated out of local/dev, and a policy or gate in front of the page. Two known hazards to plan for: the 403s that are really permission/config problems (service account not a Viewer, API not enabled, UA ID instead of numeric GA4 ID) rather than code bugs — reproduce in tinker against Analytics::fetchTopPages(...) before debugging through Filament, whose error surface hides the useful Google message; and the v1.1.0 view consolidation, which silently invalidates any published blade overrides — re-publish with --force and re-apply. Architectural guidance: use the plugin for the standard page, and write our own Filament widgets calling spatie/laravel-analytics directly for anything bespoke — don't fork vendor views. Timezone drift between app and GA4 property will cause "yesterday" totals to disagree with the GA UI; set the property timezone deliberately and document it. Given the maintainer and release-cadence risk, pin the version and budget for vendoring if it's ever load-bearing.