znanylekarz/google-bundle
A Symfony bundle from ZnanyLekarz for integrating Google APIs into PHP applications. It provides service wiring and configuration helpers so you can connect Google-powered features without repetitive client setup. Useful for Symfony projects that need a lightweight bridge to Google services.
This is a Symfony2 bundle, not a Laravel package. There is no service provider, no facade, no config/google.php and no php artisan vendor:publish. Installing it into a Laravel app with composer require znanylekarz/google-bundle will drag in Symfony 2.x constraints and does not register anything. Do not ship it; treat it as a reference implementation to mine for patterns.
Minimal path for a Laravel developer:
DependencyInjection/Configuration.php and DependencyInjection/*Extension.php. That is where the contract lives: tracker IDs, default tracker name, queue toggles, ecommerce flags, Maps API key. This tells you what a Laravel config/google.php should look like.First use case to target: a multi-tracker async snippet with a server-side page-view queue. In Laravel that means a GoogleAnalytics singleton bound in a service provider, a TrackPageView middleware that records the route/URL into the buffer, and a terminate() method that emits the queued hits into the rendered page (or forwards them server-side).
If your actual goal is analytics in a Laravel app today, stop and use a maintained alternative (spatie/laravel-analytics for reporting, GA4 gtag.js in Blade, or Google's official SDKs). Use this bundle only as a design reference.
Server-side page-view queue (the core pattern). Instead of echoing a snippet on every controller, accumulate page views in a request-scoped collector and flush them in one place. In Laravel: bind a PageViewQueue as a singleton, push from middleware or a Trackable trait, then flush in terminate() or a Blade layout that renders the queued JSON into dataLayer.
// app/Support/Analytics/PageViewQueue.php
class PageViewQueue
{
protected array $views = [];
public function push(string $path, string $title, array $trackers = []): void
{
$this->views[] = compact('path', 'title', 'trackers');
}
public function flush(): array
{
$views = $this->views;
$this->views = [];
return $views;
}
}
Multi-tracker routing. The bundle's multi-tracker support maps a logical hit onto named trackers (t1, t2, …), so a single page view can be sent to a brand property and a regional property. Port this as a config map of tracker name → measurement/property ID and a resolver that decides which trackers a given request belongs to (host, locale, tenant). Keep the resolver pure and testable.
Custom / virtual page views. AJAX and modal flows need "virtual" page views the bundle exposes as custom page views. In Laravel this is a small trackEvent() / trackVirtualPageView() API on the same singleton, pushing a distinct payload to the queue. This is the pattern most worth copying: an explicit server-side API rather than hand-written inline JS scattered across Blade templates.
Ecommerce tracking. The bundle models transactions plus line items as an ordered push (transaction, then each item, then send). Reproduce that ordering exactly in your payload builder — GA4 expects view_item_list/purchase events with items[], and order-of-operations bugs are the usual cause of "transaction recorded, items missing".
Static Maps. A thin signed-URL builder plus cache. Wrap https://maps.googleapis.com/maps/api/staticmap?... in a service that (a) signs the request when required, (b) caches the URL or the binary by a hash of the parameters, and (c) validates against the 8192-char URL cap before returning a broken <img>.
Integration tips.
dataLayer push array over multiple inline <script> blocks; one parse, no ordering surprises.analytics.js _gaq.push style (and older ga.js) Universal Analytics snippet. Universal Analytics stopped processing data in 2023. Any snippet you copy verbatim is dead code. Rebuild the architecture against gtag.js/GA4 or the Measurement Protocol.symfony/symfony 2.x constraints will conflict with any modern Laravel app. Composer will either refuse or wreck your lockfile. Never require it.terminate() and guard with an idempotency flag; be aware terminate() does not run if the process is killed.window.dataLayer in the console; use Tag Assistant or the GA Debugger extension; for ecommerce, log the payload server-side before emission so you can diff what you sent against what GA received.How can I help you explore Laravel packages today?