spatie/laravel-analytics
Laravel package to retrieve Google Analytics data with a simple API. Fetch most visited pages, visitors and page views for a given period, returning Laravel Collections. Quick to install, configurable, and works nicely in dashboards and reports.
Installation:
composer require spatie/laravel-analytics
php artisan vendor:publish --tag="analytics-config"
Configure .env with ANALYTICS_PROPERTY_ID and store the service account JSON file at storage_path('app/analytics/service-account-credentials.json').
First Use Case: Fetch today’s most visited pages:
use Spatie\Analytics\Facades\Analytics;
use Spatie\Analytics\Period;
$pages = Analytics::fetchMostVisitedPages(Period::today());
Key Files:
config/analytics.php: Configuration (property ID, credentials, cache settings).app/Providers/AppServiceProvider.php: Register facade (if not auto-discovered).Period-Based Queries:
Use Period for time ranges (e.g., Period::days(7), Period::create($start, $end)).
Example:
$visitors = Analytics::fetchVisitorsAndPageViews(Period::weeks(4));
Custom Reports:
Leverage the get() method for advanced queries:
$metrics = ['activeUsers', 'screenPageViews'];
$dimensions = ['country', 'deviceCategory'];
$results = Analytics::get(Period::months(3), $metrics, $dimensions);
Caching:
Default cache lifetime is 24 hours (configurable in analytics.php). Disable with cache_lifetime_in_minutes: 0.
Integration with Views: Pass data to Blade:
return view('analytics.dashboard', [
'topPages' => Analytics::fetchMostVisitedPages(Period::today()),
]);
Scheduled Reports: Use Laravel’s scheduler to fetch data periodically:
// app/Console/Kernel.php
$schedule->call(function () {
$data = Analytics::fetchTotalVisitorsAndPageViews(Period::days(30));
// Store in DB or send email
})->daily();
FilterExpression for complex queries (e.g., event-based filters).maxResults and offset for large datasets.try-catch for API rate limits or auth issues:
try {
$data = Analytics::fetchTopCountries(Period::today());
} catch (\Exception $e) {
Log::error("Analytics error: " . $e->getMessage());
}
Credentials Security:
.gitignore:
storage/app/analytics/service-account-credentials.json
Rate Limits:
use GuzzleHttp\Exception\RequestException;
try {
$data = Analytics::get(...);
} catch (RequestException $e) {
if ($e->getCode() === 429) {
sleep(10); // Retry after delay
retry();
}
}
GA4 vs. Universal Analytics:
Cache Invalidation:
php artisan cache:clear
Time Zone Issues:
use Carbon\Carbon;
$period = Period::create(
Carbon::now()->timezone('UTC')->startOfDay(),
Carbon::now()->timezone('UTC')->endOfDay()
);
Enable Logging:
Add to analytics.php:
'debug' => env('ANALYTICS_DEBUG', false),
Logs API requests/responses to storage/logs/analytics.log.
Validate Queries: Test queries in Google Analytics Data API Explorer first.
Common Errors:
Invalid Credentials: Verify the service account email has "Analyst" access in GA4.Property Not Found: Double-check ANALYTICS_PROPERTY_ID in .env.Metric/Dimension Not Found: Use GA4 API reference to validate names.Custom Metrics/Dimensions:
Extend the get() method for proprietary metrics:
$customMetric = Analytics::get(
Period::today(),
['customMetricName'], // Replace with your custom metric
['customDimensionName']
);
Database Storage:
Cache results in a table (e.g., analytics_reports):
// After fetching data
AnalyticsReport::updateOrCreate(
['period' => $period->toDateString()],
['data' => $data->toArray()]
);
Real-Time Dashboards: Use Laravel Echo/Pusher to broadcast updates:
// In a scheduled job
broadcast(new AnalyticsUpdate($data))->toOthers();
Multi-Property Support: Dynamically switch properties via config:
config(['analytics.property_id' => $dynamicPropertyId]);
cursor() on Collections for large datasets:
$pages = Analytics::fetchMostVisitedPages(Period::today())->cursor();
maxResults to reduce payload size.How can I help you explore Laravel packages today?