Repository navigation
Keep the arrival UTM when visitors click the site's own UTM links - #91
Conversation
Stores tag their own popups, banners and menu links with UTMs. Every page or tracked event re-read the URL and overwrote hello_utm with a fresh observed_at, so a click on the store's own popup replaced the click that brought the visitor, and single-page stores re-stamped the same UTM on every event. A UTM now counts as an arrival only when it is on the URL the document was loaded with and the visitor did not come from another page of the same site. In-site UTMs go to hello_utm_internal and are sent as internal_utm_params. Hellotext's own UTMs always count as an arrival. Re-reading the same UTM in the same document, on a reload or on a back navigation keeps observed_at. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2762d0c6ed
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
On a reloading store, a page reached from the store's own tagged link often keeps the same UTMs in its links (pagination, filters). The referrer then carries the same UTMs, which was read as a redirect of the arrival: the store's link overwrote hello_utm and the in-site marker was deleted. Same-site pages whose UTMs equal the stored in-site ones now stay in-site. Likewise, an arrival whose UTMs the store keeps on the next page is the same click, so its observed_at is no longer re-stamped. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A Hellotext link opened from an untagged page of the store compared only UTM values, so a campaign stored on an earlier visit kept its old observed_at and fired no utm-set on a genuine new click, leaving integrations such as the VTEX orderForm stamp with the old click. Hellotext clicks now keep their time only when read again during the same document or on a reload or back navigation. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7bfee56075
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Only outside arrivals cleared hello_utm_internal. A Hellotext link opened in the store and the webchat's explicit save() recorded a new click but kept the previous store banner, which every later event kept sending as internal_utm_params. All three paths now record the click through one helper that clears the in-site marker once the new click is written. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 69a5201058
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Reloading a single-page store on the store's own tagged link loads the document with the link's UTMs while the referrer is still the one the visit started with, so the link was taken as a new arrival: it overwrote the real acquisition and cleared hello_utm_internal. A reload or a back or forward navigation that restores the stored in-site UTMs now keeps them in-site; a new navigation from outside the site with the same UTMs is still an arrival. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 430d7c12aa
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
The navigation type describes the whole document, so on a single-page store it stays "reload" for links opened after reloading an untagged page. A Hellotext link opened in-page then kept an earlier visit's observed_at and fired no utm-set. The reload and back/forward rule now applies only when the UTMs were on the URL the document was loaded with; same-document re-reads still keep their time. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 24e9cf092e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Writing hello_utm fires utm-set synchronously, and the in-site cookie was only deleted afterwards, so a utm-set listener that tracked an event sent the old banner as internal_utm_params with the new click. A new click is now validated first, then the in-site UTM is cleared, then the click is written; an incomplete click still clears nothing. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7f12360889
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Only the latest in-site UTM is stored, so reloading or going back to an earlier store link after opening another one promoted it to an arrival, overwriting the acquisition and clearing the in-site cookie. A reload or back or forward navigation now never records a new click: restored UTMs other than the stored arrival are in-site, a restored Hellotext link does not replace a newer arrival, and with no arrival stored the restored UTMs are the arrival. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Problem
Stores tag their own on-site links with UTMs. does it on every home-page banner and product popup, for example
/electrohogar?utm_source=banner_a_electrohogar_12.10&utm_medium=…&utm_campaign=….The SDK treated every UTM in the URL as a new click.
new UTM()runs for everyPage: once atinitialize, and again on everytrackthat passes aurl. Each run overwrotehello_utmwith a freshobserved_at. Two things went wrong:Change
src/models/utm.jsnow sorts each UTM read from the URL into one of three cases, without depending on store naming:Page.getRootDomain; a same-site redirect that keeps the query is still the arrival. Stored inhello_utm, firesutm-setas before.utm-set. It's stored inhello_utm_internaland sent with events asinternal_utm_params(Page.trackingData), so the server can recognise the same UTM when a commerce platform reports it on the order. A new arrival clears it.utm_source=hellotext) always count as an arrival, even when opened inside the store, for example from the webchat.observed_atis kept when the same UTM is read again: in the same document (the time is at or afterperformance.timeOrigin), on a reload, or on a back/forward navigation. A new navigation to the same link stamps a new time.save()(the webchat path) keeps stamping now.Without navigation timing, the current address is treated as the one the document was loaded with, which is the old behavior.
Rollout
The VTEX pixel loads
cdn.jsdelivr.net/npm/@hellotext/hellotext/dist/hellotext.min.jsunpinned, so a release reaches VTEX stores without an app release. Purge jsDelivr after publishing. The Rails API passes event params through as-is, sointernal_utm_paramsis ignored until the server reads it.Tests
__tests__/models/utm_navigation_test.js(new, 18 cases):observed_atin the same document, on reload and on back/forward, and stamping it on a new click;page_test:internal_utm_paramsis included only when present.🤖 Generated with Claude Code