Skip to content

fix(attribution): send the marketing site's HubSpot visitor token at registration - #410

Merged
pavlo-flamingo merged 2 commits into
mainfrom
fix/hubspot-handoff-utk-attribution
Sep 15, 2026
Merged

pavlo-flamingo merged 2 commits into
mainfrom
fix/hubspot-handoff-utk-attribution

Conversation

@pavlo-flamingo

Copy link
Copy Markdown
Contributor

Problem

A visitor coming from flamingo.run lands on /auth?__hstc=…&__hssc=…&__hsfp=…, but a returning visitor's registration is attributed to the openframe.ai hubspotutk cookie — the contact gets a "direct" history instead of the marketing site's sessions and ad click.

Cause

HubSpot merges the incoming token only when its asynchronously computed browser fingerprint is already there at tracker start-up, which it is not. The GTM seed (window.hubspotutk) covers first visits only: HubSpot ignores it once a __hstc cookie exists.

Fix

  • Capture the token from __hstc into localStorage at landing (last touch — the identity semantics HubSpot itself applies) and prefer it over the local cookie as hutk at submit. Independent of the JS race.
  • Acceptance rule mirrors the container's seed: a well-formed 32-hex token next to __hsfp.
  • Test mock pointed at localStorage: the module moved there in Cross-domain attribution (flamingo.run → openframe.ai) + persistent. Persist ad params in localStorage with 90-day TTL #305 and the first-touch test has been failing since.
  • Root redirect comment: the GTM replaceState race is closed in the container; the hard fallback stays as insurance.

Caveat

Neither the seed nor this verifies the fingerprint, so a forwarded handoff link attributes its registrant to the sender's visitor — the trade-off already made for first visits.

Verified: npm run test:node 37/37 (was 30/31), lint:ci, prettier, tsc.
Sending side: flamingo-stack/multi-platform-hub#1284.

…registration, not the local cookie

A visitor who comes from flamingo.run arrives with HubSpot's cross-domain
`__hstc`, but a returning visitor's registration was still attributed to the
openframe.ai `hubspotutk` cookie: HubSpot merges the incoming token only when
its asynchronously computed browser fingerprint is ready at tracker start-up,
which it is not, and the GTM seed covers first visits only. The contact then
got a "direct" history instead of the marketing site's sessions and ad click.

Capture the token from `__hstc` into localStorage at landing (last touch, the
identity semantics HubSpot itself applies) and prefer it over the local cookie
as `hutk` at submit. Acceptance rule mirrors the container's seed: a well-formed
token next to `__hsfp`.

Also point the test mock at localStorage — the module moved there in #305 and
the first-touch test has been failing since — and note in the root redirect
that the GTM replaceState race is closed in the container.
@pavlo-flamingo
pavlo-flamingo requested review from a team as code owners September 15, 2026 18:10
@github-actions

github-actions Bot commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

🦩 Flamingo Code Review

No findings on the current head.

Mode: advisory


Need another pass? Commits pushed after this review are not reviewed automatically.

  • Review the new commits — the commits added since this review
  • Review the whole diff again — ignoring what was already reviewed

Prefer typing? Comment @flamingo-review, or @flamingo-review full. To review every push on this pull request, add the flamingo-review-always label.

React 👍/👎 on inline comments to teach the reviewer.

Started 2026-09-15 18:10 UTC · updated 2026-09-15 18:10 UTC · workflow run

@pavlo-flamingo
pavlo-flamingo merged commit fe71abb into main Sep 15, 2026
8 of 9 checks passed
@pavlo-flamingo
pavlo-flamingo deleted the fix/hubspot-handoff-utk-attribution branch September 15, 2026 19:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants