exs/lander-tracking-house-bundle
Symfony bundle that detects tracking parameters in incoming requests, stores them in cookies, and appends them to any URL through Twig filters such as appendTracking and getTracking. Includes built-in extractors for cmp, cup, cu, exid, and visit parameters, with configurable default values.
Attribution continuity across the landing-page-to-product handoff. The bundle solves one specific, real problem: a visitor arrives from a campaign or affiliate link with parameters like cmp, exid, and visit, and those values need to survive subsequent page loads and outbound link clicks. Everything in the package serves that single job — extract from request, persist to cookie, re-append to URLs via a Twig filter. For a PM, this is the smallest credible scope for "don't lose the campaign code mid-funnel."
Build-vs-buy, answered in favor of "build small." The capability is roughly a few hundred lines: read ParameterBag, write cookies, string-format query params, register a Twig extension. That is well within a sprint for one engineer. This package is best used as a specification of the pattern — the extractor/formatter service split and the compound-parameter convention ({cmp}~{exid}~{product_id}) are the genuinely useful design contributions — rather than as a dependency to pull in. Adopting it as a library adds supply-chain risk for functionality you could own outright.
Roadmap input on first-party attribution plumbing. The existence of this bundle tells you the originating org (ExSitu, a marketing agency) needed cookie-based parameter persistence and chose to build it in-house. That is the same decision your roadmap needs to make: do we own lightweight first-party attribution, or do we route this through a CDP/analytics vendor? The package covers only the "carry the parameter" slice — it does not do identity resolution, cross-device stitching, server-side event forwarding, or reporting. If your roadmap item implies any of those, this is a component, not a solution.
Scoping and estimation anchor for an "affiliate/referral code propagation" feature. Concretely useful when sizing work: configurable defaults per parameter, a named-formatter mechanism so different destinations get different parameter sets, and placeholder replacement so a URL template can be built once and populated at render time. That is a realistic MVP surface, and knowing it exists keeps estimates honest — this is days of work, not a quarter's platform initiative.
Framework reality check that should gate the decision. This is a Symfony bundle, not a Laravel package. The install instructions reference AppKernel::registerBundles, YAML service tags (exs_tracking.parameter_extracter), Twig filters, and Symfony's ParameterBag. There is no service provider, no Blade directive, no config file in Laravel's shape. In Laravel you would be reimplementing the concept, not installing the package. Any decision recorded as "reuse this package" should be corrected to "reimplement this pattern."
A visible checklist of what a production version must add. Reading the package against modern requirements is itself a useful artifact: it documents the gap between "captures parameters" and "tracking we can ship." That gap list (consent, cookie flags, lifetime policy, PII scrubbing, tests) is a better input to planning than the package itself.
Worth studying, when:
cup / cu / cuvp / uv family, each defined by which fields it packs and in what order, is a tidy contract worth copying if you have to interoperate with an existing ad or affiliate network.Look elsewhere, when:
Secure/SameSite attributes, or PII handling. Under GDPR/ePrivacy/CCPA this is a material omission, not a polish item. Retrofitting consent into a "write the cookie on every request" design means restructuring the extraction flow, not adding a flag.Adoption verdict: do not add as a production dependency in any framework. Read the README, copy the compound-parameter convention and the extractor/formatter split, and write your own ~150 lines with consent gating, signed or allowlisted parameter values, hardened cookies, and tests. On Laravel specifically, that means middleware for capture-and-persist plus a URL helper for append — a day or two of work that you fully control.
For executives: This is a small, MIT-licensed Symfony add-on from a marketing agency that does one narrow thing well — it reads campaign and affiliate identifiers off an inbound link, remembers them in a cookie, and automatically tags outbound links so the attribution survives the journey from a landing page into the product. It is not a Laravel package and not an analytics platform; it does no reporting, identity matching, or ad-platform integration. Treat it as a design reference, not a purchase or a dependency. The strategic value is that it lets us scope our own attribution plumbing in days rather than commissioning a platform, and it gives us a clear checklist of what a production version must add — consent handling under GDPR, cookie hardening, and tests — none of which this package addresses. Recommendation: reimplement the pattern in-house with those gaps closed; do not adopt the package.
For engineering: The transferable ideas are two. First, a clean split between extractors (pull a value from query, cookie, or a configured default, in that priority) and formatters (decide which parameters to append to which destination). Second, a compound-parameter convention — a single query key carrying a tilde-delimited tuple such as {cmp}~{exid}~{product_id} — which keeps downstream links to one ugly parameter instead of three. In Laravel this becomes middleware that captures and persists into a cookie on the way in, plus a URL helper or Blade directive that appends on the way out. What we must add that the original lacks: consent gating before any cookie write, explicit lifetime and Secure/SameSite attributes, validation and encoding of inbound values so users cannot inject arbitrary strings into our outbound URLs, and test coverage. Also note the framework mismatch up front — nothing here is installable on our stack, so any estimate should assume a rewrite, not an integration.
How can I help you explore Laravel packages today?