Download the PHP package fsuuaas/utm-tracker without Composer
On this page you can find all versions of the php package fsuuaas/utm-tracker. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download fsuuaas/utm-tracker
More information about fsuuaas/utm-tracker
Files in fsuuaas/utm-tracker
Package utm-tracker
Short Description Structured UTM capture (frontend JS + Blade component) and persistence (polymorphic UtmRecord model) for Laravel apps.
License MIT
Homepage https://github.com/fsuuaas/utm-tracker
Informations about the package utm-tracker
fsuuaas/utm-tracker
Structured UTM capture and persistence for Laravel apps: a first-party
capture script with proper multi-touch attribution, a Blade component that
populates any form automatically, and a polymorphic UtmRecord model that
attaches itself to whatever your app creates.
What it does
- Frontend (
resources/js/utm-capture.js) reads UTM params from the URL on every page load, classifies the traffic, and writes one first-party cookie tracking:- last-touch — the most recent campaign, replaced as a whole snapshot
(a bare
?gclid=...never blanks a previously capturedutm_source); - first-touch — locked once, for the whole touch, the first time any campaign is seen;
- a multi-touch funnel chain (
mcf_*, e.g.newsletter>google), with the delimiter escaped so a campaign value containing>can't corrupt it; - referrer classification — organic search, social, referral or direct
are all recorded, not just query-string UTMs. A direct visit never
overwrites an existing campaign (configurable, see
direct_handling). - It also reads and upgrades two older cookie formats in place (see Migrating from an older cookie, below) and keeps the cookie under the browser's ~4KB limit by shrinking the least-important fields first.
- last-touch — the most recent campaign, replaced as a whole snapshot
(a bare
- Blade components:
<x-utm-tracker::script />(include once per layout) and<x-utm-tracker::fields />(drop inside any<form data-utm-track>). Forms are populated on load, when they're injected into the DOM later (modals, AJAX), and again immediately before submit — so existingnew FormData(form)code needs no changes. - Backend:
HasUtm+SavesUtmconcerns and a polymorphicUtmRecordmodel (utmable_type/utmable_id) persist whatever UTM data arrives with a model's creation request. Recording is deferred until the surrounding transaction commits and never throws — a malformed value is truncated, not rejected, so attribution can never break the write it rides along with.
Requirements
PHP 8.1+, Laravel 10 / 11 / 12.
Install
If you're consuming it via a VCS repository entry instead of Packagist:
Frontend-only usage
For an app that only captures and submits attribution (forms POST to an external API, e.g. cc-website → breeze10):
<x-utm-tracker::fields /> renders one hidden input per field the browser is
responsible for (utm_source, first_utm_source, mcf_utm_source,
referrer, landing_page, session_count, …). name always stays plain
and unprefixed — only id takes the prefix — so the payload your backend
receives is unaffected by which form on the page it came from.
ip_address and user_agent are deliberately never rendered as hidden
inputs: they're resolved server-side from the request, so a submitter can't
forge them.
Backend usage
A model using both concerns records a UtmRecord the moment it's created —
no controller changes needed. Two accessors are available:
To capture explicitly instead of (or in addition to) the automatic hook:
Fsuuaas\UtmTracker\Traits\HasUtm and Traits\SavesUtm still exist as thin
aliases over the Concerns\ versions above, so an app already using the old
namespace keeps working without touching its models.
An app that already has a utm_records table
Point the package at your existing model instead of publishing the create-table migration, and add indexing separately:
Querying
Scopes are named for what they filter (source, medium, campaign,
term, content, gclid, ip, landingPage, userAgentLike, between,
attributed) — not withSource() etc., since in Eloquent with* means
eager-loading.
Config
defer_until_commit matters for tests: RefreshDatabase wraps everything in
a transaction that never commits, so set this to false in phpunit.xml if
your tests assert on utm_records rows.
Adding a field
The field list is defined once, in the registry — not duplicated across the migration, the model, the Blade view and the JS config. Extend it from a service provider:
A registered field with no matching column stays uncaptured on a database
that hasn't migrated for it yet. UtmSchema::missingColumns() reports what's
out of sync so you know when a migration is needed.
Migrating from an older cookie
The capture script upgrades two prior formats in place, on first read, and never deletes the old cookie — so anything else still reading it keeps working during the transition:
- a plain-JSON
utm_datacookie with 5 fields (the original hand-rolled cc-website script); - a base64-encoded
traffic_sourcecookie with 23 keys (the breeze10tracking.jsformat) — including converting its ISO-8601 timestamps to the epoch-millisecond format this package uses.
List any cookie names you want upgraded-from in legacy_cookies.
JS API
Testing
License
MIT.
All versions of utm-tracker with dependencies
illuminate/database Version ^10.0|^11.0|^12.0
illuminate/http Version ^10.0|^11.0|^12.0
illuminate/support Version ^10.0|^11.0|^12.0