Weave 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 Gamp Laravel Package

irazasyed/laravel-gamp

Laravel GAMP is a Laravel wrapper for Google Analytics Measurement Protocol, enabling server-side tracking of events, page views, and ecommerce transactions. It offers a simple, fluent API to send analytics hits from your backend without client-side JavaScript.

View on GitHub
Deep Wiki
Context7

Getting Started

composer require irazasyed/laravel-gamp
php artisan vendor:publish --tag=config   # picks up config/gamp.php

Laravel 10 (which v1.10 explicitly adds support for) auto-discovers LaravelGAMPServiceProvider and the GAMP facade — no manual registration in config/app.php unless you're on a pre-5.5 skeleton. Then set your property ID in config/gamp.php (keep the value in .env and reference it, so it isn't committed):

// config/gamp.php
'tracking_id' => env('GAMP_TRACKING_ID', 'UA-XXXXXXXX-1'),

The first thing to read is config/gamp.php — its keys map almost 1:1 onto Measurement Protocol parameters, and it tells you what the package will send by default. The second thing to read is the facade: every set*() returns $this, and exactly one terminal send*() method dispatches the HTTP request.

The canonical first use case is a server-side event that client-side JS can never see:

use Irazasyed\LaravelGAMP\Facades\GAMP;

GAMP::setClientId((string) $user->id)
    ->setEventCategory('Subscription')
    ->setEventAction('cancelled')
    ->setEventLabel($plan->slug)
    ->setEventValue(1)
    ->sendEvent();

Implementation Patterns

Keep the fluent chain short and wrap it. Analytics is a side-effect you never want in a critical path. Put every call behind a queued job or dispatch(...)->afterResponse():

dispatch(function () use ($order) {
    GAMP::setClientId((string) $order->user_id)
        ->setEventCategory('Order')
        ->setEventAction('placed')
        ->setEventValue((int) $order->total)
        ->sendEvent();
})->afterResponse();

Centralize in one service class. A thin AnalyticsTracker with methods like orderPlaced(Order $o) means one place to mock, one place to change when you migrate, and no GAMP:: calls scattered through controllers. Bind it in a service provider and inject it.

Pick a stable client_id and be consistent. This is the identity GA stitches hits to. Use $user->id (or a persisted UUID column) — never session()->getId(), which rotates and differs per device/server. For guest traffic, mint a UUID on first touch and store it in a cookie or the users table. If you don't set it, you get an auto-generated value and all your attribution falls apart.

Hook into domain events, not controllers. Event::listen(OrderPlaced::class, ...) or a model observer keeps tracking tied to what happened rather than to which route happened to handle it — so queued jobs, console commands, and webhooks are all covered for free.

E-commerce must be ordered. sendTransaction() before sendItem(); each item is its own hit with a shared transaction ID. Looping items is N+1 HTTP requests — see gotchas.

Server-side pageviews for non-JS surfaces. Emails, PDFs, API consumers, and redirect endpoints can all call sendPageView() with setDocumentPath(), setDocumentTitle(), and setDocumentHostName() to land in the same property as the browser beacon.

Testing. Either mock the facade (GAMP::shouldReceive('sendEvent')->once()) or Http::fake() and assert the query string — the latter also proves your parameters are actually correct, which facade mocks won't catch.

Environment gate. Add a null wrapper or an early return for local/testing so dev traffic and CI runs never pollute production reporting.

Gotchas and Tips

The big one: Universal Analytics is dead. This package speaks Measurement Protocol v1 (UA) — www.google-analytics.com/collect, UA- tracking IDs, v=1. Google stopped processing UA hits in 2023. GA4 uses a different protocol entirely: POST to /mp/collect with measurement_id + api_secret and a JSON events[] body. If your property is GA4, this package will appear to work (the endpoint returns 204 and swallows everything) while recording nothing. Treat v1.10 as a maintenance release for legacy UA setups and plan a migration to a GA4 client or a hand-rolled Http::post() — it's about 20 lines and removes the dependency risk.

Silent failures are the default. The production endpoint returns 204 No Content whether your payload was perfect or nonsense. When hits aren't landing, temporarily point the config at the validation endpoint (https://www.google-analytics.com/debug/collect) — it returns a JSON body with hitParsingResult[].valid and per-parameter messages. Do this before you start doubting your client ID.

Synchronous HTTP in the request path. Each send*() is a blocking network call. A loop over 20 order items adds 20 round trips to your checkout response. Queue it, or accept the latency knowingly.

Never let tracking throw. Wrap calls in try/catch (\Throwable) and log-and-continue — a DNS blip or Google 5xx must not fail a payment.

PII and GDPR. Enable anonymize_ip in config, and never put emails, names, or addresses into event labels/categories — that's a GA ToS violation and a data-protection problem. Send hashed IDs or slugs only.

setUserId ≠ setClientId. They're distinct parameters with distinct purposes; setting only the former still leaves GA without a client identity.

Config caching. Values live in config/gamp.php referenced from .env; after changing GAMP_TRACKING_ID on a production box you must php artisan config:cache again or the old value persists.

Upgrading to v1.10. The release is a Laravel 10 compatibility bump (framework constraint widened), not an API change — your GAMP:: chains keep working. Still re-run your test suite: the transitive Illuminate/HTTP updates can shift behaviour, and if you're pinned below Laravel 8/9 check whether the new constraint drops you. Also re-verify the published config/gamp.php against the package default after any upgrade, since config files aren't overwritten by vendor:publish.

Extension point. The facade is a thin wrapper over the underlying theiconic/php-ga-measurement-protocol client, which exposes the full Measurement Protocol surface. If you need a parameter the Laravel wrapper doesn't have a setter for, reach through to the underlying instance rather than forking the package.

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.
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route