# Laravel Google Tag Manager This package provides a seamless Google Tag Manager integration for Laravel applications. It simplifies the management of GTM's dataLayer by offering a clean PHP API to set tracking data, handle events, and manage tag triggers without manually editing JavaScript. The package supports both immediate data injection and flash data for post-redirect scenarios. The core functionality revolves around the GoogleTagManager class which manages a DataLayer object that gets rendered as JSON in your page's head section. It includes middleware for handling session-based flash data, a facade for convenient access throughout your application, and Blade view components for easy script inclusion. The package supports dot notation for nested data structures, macros for reusable tracking patterns, and provides utilities for converting arrays to JSON for dynamic client-side pushing. ## Installation and Configuration Install via Composer and configure your GTM container ID ```bash composer require spatie/laravel-googletagmanager php artisan vendor:publish --provider="Spatie\GoogleTagManager\GoogleTagManagerServiceProvider" --tag="config" ``` ```php // config/googletagmanager.php return [ 'id' => env('GOOGLE_TAG_MANAGER_ID', 'GTM-XXXXXX'), 'enabled' => env('GOOGLE_TAG_MANAGER_ENABLED', true), 'sessionKey' => '_googleTagManager', 'domain' => 'www.googletagmanager.com', // or 'gtm.yourdomain.com' for server-side GTM ]; ``` ```php // app/Http/Kernel.php - Register middleware for flash functionality protected $middleware = [ \Illuminate\Session\Middleware\StartSession::class, \Spatie\GoogleTagManager\GoogleTagManagerMiddleware::class, ]; ``` ```blade {{-- resources/views/layouts/app.blade.php --}}
@include('googletagmanager::head') @include('googletagmanager::body') {{-- Your content --}} ``` ## Setting Basic DataLayer Values Add data to the dataLayer that renders on page load ```php // app/Http/Controllers/ProductController.php use Spatie\GoogleTagManager\GoogleTagManagerFacade as GoogleTagManager; class ProductController extends Controller { public function show($id) { $product = Product::findOrFail($id); // Simple key-value pairs GoogleTagManager::set('pageType', 'productDetail'); GoogleTagManager::set('productId', $product->id); // Array data GoogleTagManager::set([ 'ecommerce' => [ 'detail' => [ 'products' => [[ 'name' => $product->name, 'id' => $product->id, 'price' => $product->price, 'brand' => $product->brand, 'category' => $product->category, ]] ] ] ]); // Dot notation for nested values GoogleTagManager::set('user.id', auth()->id()); GoogleTagManager::set('user.tier', auth()->user()->membership_tier); return view('products.show', compact('product')); } } ``` ```html ``` ## Flashing Data for Next Request Store dataLayer values that persist through redirects ```php // app/Http/Controllers/ContactController.php use Spatie\GoogleTagManager\GoogleTagManagerFacade as GoogleTagManager; class ContactController extends Controller { public function show() { // This data renders on current page GoogleTagManager::set('pageType', 'contact'); return view('contact.form'); } public function store(Request $request) { $validated = $request->validate([ 'name' => 'required', 'email' => 'required|email', 'message' => 'required', ]); // Send email, store in database, etc. // Flash data for the NEXT request (after redirect) GoogleTagManager::flash('event', 'form_submission'); GoogleTagManager::flash('formType', 'contact'); GoogleTagManager::flash('conversionValue', 100); // Flash also supports arrays and dot notation GoogleTagManager::flash([ 'user' => [ 'action' => 'contacted', 'timestamp' => now()->toIso8601String(), ] ]); return redirect()->route('contact.show') ->with('success', 'Thank you for contacting us!'); } } ``` ```html ``` ## Pushing Events After Page Load Push data to dataLayer after initial page load using the push functionality ```php // app/Http/Controllers/AuthController.php use Spatie\GoogleTagManager\GoogleTagManagerFacade as GoogleTagManager; class AuthController extends Controller { public function login(Request $request) { $credentials = $request->validate([ 'email' => 'required|email', 'password' => 'required', ]); if (Auth::attempt($credentials)) { // Push event that fires on page load via addEventListener GoogleTagManager::push([ 'event' => 'user_login', 'method' => 'email', 'userId' => auth()->id(), ]); return redirect()->intended('dashboard'); } return back()->withErrors(['email' => 'Invalid credentials']); } public function oauthCallback() { // Handle OAuth authentication $user = $this->handleOAuthCallback(); if ($user->wasRecentlyCreated) { // Push multiple events - order matters GoogleTagManager::flashPush(['event' => 'sign_up', 'method' => 'OAuth']); } GoogleTagManager::flashPush(['event' => 'login', 'method' => 'OAuth']); return redirect()->intended(); } } ``` ```html ``` ## Using DataLayer Class Directly Work with DataLayer objects for custom implementations ```php use Spatie\GoogleTagManager\DataLayer; use Spatie\GoogleTagManager\GoogleTagManagerFacade as GoogleTagManager; // Create standalone DataLayer instance $dataLayer = new DataLayer(); $dataLayer->set('product.name', 'Example Product'); $dataLayer->set('product.price', 29.99); // Convert to JSON echo $dataLayer->toJson(); // Output: {"product":{"name":"Example Product","price":29.99}} // Convert to array $array = $dataLayer->toArray(); // Output: ['product' => ['name' => 'Example Product', 'price' => 29.99]] // Access the main GoogleTagManager's DataLayer $mainDataLayer = GoogleTagManager::getDataLayer(); $currentData = $mainDataLayer->toArray(); // Clear all data $dataLayer->clear(); ``` ## Dumping Arrays to JSON for Client-Side Use Embed product data in HTML attributes for JavaScript tracking ```php // app/Http/Controllers/CategoryController.php class CategoryController extends Controller { public function show($slug) { $category = Category::where('slug', $slug)->firstOrFail(); $products = $category->products()->paginate(20); GoogleTagManager::set('pageType', 'category'); GoogleTagManager::set('categoryName', $category->name); return view('category.show', compact('category', 'products')); } } ``` ```blade {{-- resources/views/category/show.blade.php --}}${{ $product->price }}
@endforeach