Drop default UTM params from console CTAs - #8141
Conversation
The nav CTAs injected fallback UTMs (utm_source=website, utm_medium=<page>, utm_campaign=signup/login) for visitors without campaign params, permanently stamping ~16% of monthly signups' first-touch attribution as "website" and masking their true organic/direct origin. Real campaign UTMs still pass through, and the localStorage persistence layer keeps injecting stored first/last touch attribution on console link clicks. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (11)
WalkthroughThe change removes default UTM propagation from blog and site navigation. Console CTAs now preserve explicit query parameters and record CTA clicks. Direct links use untracked destinations. A site development launch configuration runs on port 3106. ChangesNavigation and CTA tracking
Site development launch
Estimated code review effort: 3 (Moderate) | ~25 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Comment |
|
The latest updates on your projects. Learn more about Argos notifications ↗︎
|
There was a problem hiding this comment.
🧹 Nitpick comments (1)
packages/ui/src/components/web-navigation.tsx (1)
80-81: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winAdd regression coverage for the new console URL contract.
When
utmis absent, assert that both login and signup links have no query string. Whenutmcontains exactutm_*values, assert that both links preserve them and do not addutm_campaignunless it was supplied.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/ui/src/components/web-navigation.tsx` around lines 80 - 81, Add regression tests around the link generation in the web navigation component, covering absent utm and exact utm_* inputs. Assert loginHref and signupHref omit the query string when utm is absent, preserve supplied UTM values unchanged, and do not add utm_campaign unless explicitly provided.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@packages/ui/src/components/web-navigation.tsx`:
- Around line 80-81: Add regression tests around the link generation in the web
navigation component, covering absent utm and exact utm_* inputs. Assert
loginHref and signupHref omit the query string when utm is absent, preserve
supplied UTM values unchanged, and do not add utm_campaign unless explicitly
provided.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 9a8d1161-905c-4bb6-aa5e-75df8b541943
📒 Files selected for processing (6)
.claude/launch.jsonapps/blog/src/app/(blog)/layout.tsxapps/blog/src/components/navigation-wrapper.tsxapps/site/src/app/layout.tsxapps/site/src/components/navigation-wrapper.tsxpackages/ui/src/components/web-navigation.tsx
Same fix as the nav: the studio, postgres, orm, and pricing pages had utm_source=website literals baked into their console links, stamping organic visitors' attribution. The persistence layer still injects real campaign UTMs at click time. Also removed the defaultUtm prop from the unused ConsoleCtaButton. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Per the pris.ly owner, the hero and compute CTAs now link directly: pdp -> console.prisma.io/sign-up, and the compute pricing/docs/blog shortlinks -> their real prisma.io destinations. Direct console links let the UTM persistence layer inject real campaign attribution at click time, which the external shortener host bypassed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The cta_click GA4 event (and its Google Ads conversion import) only fired from the blog's CTA, while the actual site nav Login/Get started buttons and the homepage/compute/pricing/postgres/studio hero and body CTAs linked straight to console.prisma.io with no tracking at all. The other GA4-imported conversion action, cta_click_auto, fires on every link click sitewide and is too noisy to be a useful signal. Also adds https://www.googletagmanager.com to img-src, which GTM's own container diagnostics flagged as Urgent ("likely impacting measurement") across 61 pages. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Why
The nav CTAs to console.prisma.io injected fallback UTMs (
utm_source=website,utm_medium=<page slug>,utm_campaign=signup/login) whenever the visitor had no campaign params of their own. Since console and the website share the same PostHog project, this polluted attribution:$initial_utm_sourcepermanently stamped aswebsite— organic/direct visitors whose true first-touch is now masked forever.utm_sourceoverwritten towebsite.utm_source=websiteis by far the largest non-null source on console pageviews (27.9k of ~150k in 14 days), dwarfing every real channel.What changed
NavigationWrappers — CTAs now carry UTMs only when the visitor's current URL actually has them.utm_campaign=signup/loginfallback in the sharedWebNavigationconsole-href builder.first_utm_*) on console link clicks from later pages.Verified locally
https://console.prisma.io/sign-upwith no params.?utm_source=twitter&utm_medium=paid&utm_campaign=launch→ CTAs carry those exact params.first_utm_*params.Also included: page-level CTAs
The studio, postgres, ORM, and pricing pages had the same defaults hardcoded as literal query strings (
utm_source=website&utm_medium=<page>&utm_campaign=cta) on their console links — dropped those too, and removed thedefaultUtmprop from the unusedConsoleCtaButton. The pris.ly CTA shortlinks are now replaced with direct URLs too (confirmed with the pris.ly owner):pris.ly/pdp->console.prisma.io/sign-upon the homepage, compute, and blog CTAs, and the compute pricing/docs/blog shortlinks -> their real prisma.io destinations. Direct console links let the persistence layer inject real campaign attribution at click time, which the external shortener host bypassed. Footer social shortlinks (pris.ly/github etc.) carry no UTMs and are untouched.Heads-up for dashboards
After deploy, UTM-less console signups will have no utm_source instead of
website. Reports keying on$initial_utm_sourcewill show this segment as null/organic; anything filteringutm_source = 'website'will see that bucket drain. Existing persons' stamped values are unchanged.🤖 Generated with Claude Code
Summary by CodeRabbit
Bug Fixes
Improvements