spatie/laravel-googletagmanager
Laravel package for easy Google Tag Manager integration. Manage the JavaScript dataLayer from PHP, push variables and events, and include GTM scripts cleanly in your app with simple configuration and helpers.
Installation:
composer require spatie/laravel-googletagmanager
Publish the config file:
php artisan vendor:publish --provider="Spatie\GoogleTagManager\GoogleTagManagerServiceProvider"
Configuration:
Edit .env to include your GTM ID:
GOOGLE_TAG_MANAGER_ID=GTM-XXXXXX
Or set it in config/googletagmanager.php:
'id' => env('GOOGLE_TAG_MANAGER_ID', 'GTM-XXXXXX'),
First Use Case:
Add the GTM script to your layout (e.g., resources/views/layouts/app.blade.php):
@googleTagManager
This outputs the container snippet:
<!-- Google Tag Manager -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-XXXXXX');</script>
<!-- End Google Tag Manager -->
Basic Tag Injection:
Use the @googleTagManager directive in Blade views to inject the container snippet globally.
@googleTagManager
Conditional Tagging: Dynamically enable/disable GTM based on environment or user roles:
if (app()->environment('production')) {
echo \Spatie\GoogleTagManager\GoogleTagManager::container();
}
Event Tracking: Push dataLayer events from Laravel logic:
use Spatie\GoogleTagManager\GoogleTagManager;
// In a controller or service
GoogleTagManager::push([
'event' => 'user_registered',
'user_id' => auth()->id(),
'email' => auth()->user()->email,
]);
Middleware Integration: Track page views or user actions via middleware:
namespace App\Http\Middleware;
use Closure;
use Spatie\GoogleTagManager\GoogleTagManager;
class TrackPageViews
{
public function handle($request, Closure $next)
{
GoogleTagManager::push([
'event' => 'page_view',
'page_url' => $request->url(),
'page_title' => $request->route()->getName(),
]);
return $next($request);
}
}
View-Level Events: Trigger events in Blade templates:
@googleTagManager([
'event' => 'product_viewed',
'product_id' => $product->id,
'product_name' => $product->name,
])
Dynamic GTM ID: Override the GTM ID per request (e.g., for multi-tenant apps):
config(['googletagmanager.id' => 'GTM-' . $tenant->gtm_id]);
Custom Data Layer Structure:
Extend the dataLayer array with custom properties:
GoogleTagManager::push([
'user' => [
'id' => auth()->id(),
'segment' => auth()->user()->segment,
],
'custom_dimensions' => [
'dimension1' => 'value1',
],
]);
Server-Side Tagging (SST): Use the package to send server-side events to GTM (requires GTM Server-Side setup):
GoogleTagManager::sendServerEvent([
'event' => 'purchase',
'transaction_id' => $order->id,
'value' => $order->total,
]);
Integration with Analytics:
Combine with other Spatie packages (e.g., laravel-analytics) for unified tracking:
use Spatie\Analytics\Analytics;
use Spatie\GoogleTagManager\GoogleTagManager;
Analytics::trackPageView();
GoogleTagManager::push(['event' => 'page_view']);
Missing GTM ID:
.env or config/googletagmanager.php has the correct GOOGLE_TAG_MANAGER_ID.Caching Issues:
php artisan view:clear
@googleTagManager in uncached views or layouts.Data Layer Conflicts:
push() calls may overwrite dataLayer values.Environment-Specific Tags:
if (!app()->environment('local')) {
echo \Spatie\GoogleTagManager\GoogleTagManager::container();
}
Async Script Blocking:
Verify Output: Inspect the rendered HTML to confirm the GTM snippet is present:
<!-- Google Tag Manager -->
<script>...</script>
<!-- End Google Tag Manager -->
Check DataLayer:
Use browser DevTools (console.log(window.dataLayer)) to verify pushed events.
GTM Preview Mode: Enable GTM’s preview mode to test events in real-time without publishing.
Logging: Add debug logs for critical events:
\Log::debug('GTM Event', [
'event' => $eventData,
'dataLayer' => \Spatie\GoogleTagManager\GoogleTagManager::getDataLayer(),
]);
Custom Directives: Extend Blade directives for project-specific needs:
// In AppServiceProvider@boot()
Blade::directive('customGtm', function ($expression) {
return "<?php echo \\Spatie\\GoogleTagManager\\GoogleTagManager::container($expression); ?>";
});
Usage:
@customGtm(['custom' => 'value'])
Override Container Method: Modify the container output in a service provider:
// app/Providers/GoogleTagManagerServiceProvider.php
public function boot()
{
\Spatie\GoogleTagManager\GoogleTagManager::macro('container', function ($options = []) {
$html = \Spatie\GoogleTagManager\GoogleTagManager::getContainerHtml();
return str_replace('GTM-XXXXXX', 'GTM-' . config('custom.gtm_id'), $html);
});
}
Event Listeners: Trigger GTM events from Eloquent observers or Laravel events:
// In UserObserver@created()
\Spatie\GoogleTagManager\GoogleTagManager::push([
'event' => 'user_created',
'user_id' => $user->id,
]);
Testing: Mock GTM in tests to avoid real requests:
use Spatie\GoogleTagManager\GoogleTagManager;
// In a test
GoogleTagManager::shouldReceive('container')->andReturn('<script>mock</script>');
How can I help you explore Laravel packages today?