Weave Code
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

Fetch Google Analytics data in Laravel via a simple facade. Query visitors, pageviews, most visited pages and more for a given period, returning Collections. Easy install, configurable credentials, and ready-to-use methods for common reports.

View on GitHub
Deep Wiki
Context7
## Getting Started

### Minimal Setup
1. **Installation**: Add the package via Composer:
   ```bash
   composer require spatie/laravel-analytics
  1. Configuration: Publish the config file and set your ANALYTICS_PROPERTY_ID and service_account_credentials_json in .env:

    php artisan vendor:publish --tag="analytics-config"
    

    Update .env:

    ANALYTICS_PROPERTY_ID=your-ga4-property-id
    
  2. Credentials: Download the service account JSON from Google Cloud Console and place it in storage/app/analytics/service-account-credentials.json (ensure it’s excluded from Git).

  3. Grant Permissions: Add the service account email (from the JSON) as an "Analyst" in your GA4 property’s Property Access Management.

  4. First Query: Fetch basic data in a controller or service:

    use Spatie\Analytics\Facades\Analytics;
    use Spatie\Analytics\Period;
    
    $visitors = Analytics::fetchVisitorsAndPageViews(Period::days(7));
    

Implementation Patterns

Common Workflows

  1. Dashboard Analytics:

    • Fetch aggregated data for a dashboard (e.g., daily/weekly trends):
      $trends = Analytics::fetchVisitorsAndPageViewsByDate(Period::days(30));
      
    • Group by date and format for charts (e.g., using Laravel’s transform()):
      $chartData = $trends->transform(function ($item) {
          return [
              'date' => $item['date'],
              'visitors' => $item['activeUsers'],
              'pageviews' => $item['screenPageViews'],
          ];
      });
      
  2. Content Performance:

    • Identify top-performing pages:
      $topPages = Analytics::fetchMostVisitedPages(Period::days(30), 10);
      
    • Filter for specific page types (e.g., blog posts) using get() with dimensions:
      $blogTraffic = Analytics::get(
          Period::days(30),
          ['screenPageViews'],
          ['pagePath'],
          10,
          [],
          0,
          null,
          false,
          null,
          new FilterExpression([
              'filter' => new Filter([
                  'field_name' => 'pagePath',
                  'string_filter' => new StringFilter([
                      'match_type' => MatchType::CONTAINS,
                      'value' => '/blog/',
                  ]),
              ]),
          ])
      );
      
  3. Audience Insights:

    • Segment users by device/OS:
      $devices = Analytics::fetchTopBrowsers(Period::days(30));
      $os = Analytics::fetchTopOperatingSystems(Period::days(30));
      
    • Combine with custom dimensions (e.g., user roles) via get():
      $userSegments = Analytics::get(
          Period::days(30),
          ['activeUsers'],
          ['userType', 'customDimension1'], // customDimension1 = "User Role"
          5
      );
      
  4. Event Tracking:

    • Query custom events (e.g., form submissions):
      $eventData = Analytics::get(
          Period::days(7),
          ['eventCount'],
          ['eventName'],
          10,
          [OrderBy::metric('eventCount', false)],
          0,
          new FilterExpression([
              'filter' => new Filter([
                  'field_name' => 'eventName',
                  'string_filter' => new StringFilter([
                      'match_type' => MatchType::EXACT,
                      'value' => 'form_submitted',
                  ]),
              ]),
          ])
      );
      
  5. Caching Strategies:

    • Leverage the built-in caching (default: 24 hours) for frequent queries:
      // Override cache lifetime in config/analytics.php
      'cache_lifetime_in_minutes' => 60 * 6, // 6 hours
      
    • Bypass cache for real-time data (set to 0 in config).
  6. Pagination:

    • Use offset and maxResults for large datasets:
      $page1 = Analytics::get(Period::days(30), ['screenPageViews'], [], 10, [], 0);
      $page2 = Analytics::get(Period::days(30), ['screenPageViews'], [], 10, [], 10);
      

Gotchas and Tips

Pitfalls

  1. Credentials Security:

    • Never commit the service-account-credentials.json to version control. Add it to .gitignore:
      storage/app/analytics/service-account-credentials.json
      
    • Rotate keys periodically via Google Cloud Console to revoke access if compromised.
  2. GA4 Property ID:

    • Ensure the ANALYTICS_PROPERTY_ID matches the GA4 property ID (not Universal Analytics). Format: properties/12345678.
    • Verify permissions in Property Access Management—delays here can cause silent failures.
  3. Quota Limits:

    • Google Analytics Data API has quotas. Monitor usage in Google Cloud Console to avoid quotaExceeded errors.
    • Solution: Implement exponential backoff in retries or cache aggressively.
  4. Date Ranges:

    • GA4 requires dates to be in UTC. Use Carbon for consistency:
      $period = Period::create(
          Carbon::now()->timezone('UTC')->startOfDay()->subDays(7),
          Carbon::now()->timezone('UTC')->endOfDay()
      );
      
    • Avoid open-ended ranges (e.g., Period::allTime()) to prevent quota spikes.
  5. Dimension/Metric Combinations:

    • Not all dimension/metric pairs are valid. Test with small maxResults (e.g., 5) first.
    • Error: Invalid dimension/metric combination → Check GA4 API docs for valid pairs.
  6. Caching Quirks:

    • Cache invalidation: Clear manually if data is stale:
      php artisan cache:clear
      
    • Debugging: Disable caching temporarily (cache_lifetime_in_minutes = 0) to test live data.
  7. Filter Complexity:

    • Nested filters (e.g., AND/OR logic) require multiple FilterExpression objects. Use the FilterExpression::combine() method:
      $filter1 = new FilterExpression([/* ... */]);
      $filter2 = new FilterExpression([/* ... */]);
      $combinedFilter = FilterExpression::combine($filter1, $filter2, 'AND');
      

Debugging Tips

  1. Enable Debugging:

    • Set the GOOGLE_APPLICATION_CREDENTIALS env variable to the JSON path for verbose errors:
      GOOGLE_APPLICATION_CREDENTIALS=storage/app/analytics/service-account-credentials.json
      
    • Check Laravel logs for Google\ApiCore\ApiException details.
  2. Validate Responses:

    • Inspect raw responses with dd():
      $response = Analytics::get(/* ... */);
      dd($response->toArray());
      
    • Look for rowCount, metadata, and errors in the response.
  3. Common Errors & Fixes:

    Error Solution
    Invalid credentials Regenerate JSON key in Google Cloud Console.
    Property not found Verify ANALYTICS_PROPERTY_ID format and permissions.
    Quota exceeded Reduce query frequency or upgrade quota in Google Cloud Console.
    Invalid dimension/metric Cross-reference with GA4 API schema.
    Cache miss but no data returned Check if the period is valid (e.g., not in the future).

Extension Points

  1. Custom Metrics/Dimensions:
    • Extend the get() method for unsupported metrics by using the underlying GoogleAnalyticsDataClient:
      use Google\Analytics\Data\V1beta\RunReportRequest;
      use Google\Analytics\Data\V1beta\Dimension;
      use Google\Analytics\Data\V1beta\Metric;
      
      $client = app(\Spatie\Analytics\AnalyticsService::class)->client();
      $request = new RunReportRequest([
          'property' => 'properties/' . config('analytics.property_id'),
          'dimensions' => [new Dimension(name: 'customDimension1')],
          'metrics' => [new Metric(name: 'customMetric1')],
          'dateRanges'
      
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.
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope
anil/file-picker
broqit/fields-ai