Repository navigation
Restore marketing-site signup attribution with a ref fallback on Console links - #8418
Conversation
PR #8141 dropped the utm_source=website default from Console CTAs because it froze "website" into organic visitors' $initial_utm_source. It was also the only signal the site sent for visitors without campaign params, so since Aug 11 the console cannot tell a signup that came from prisma.io from one that typed console.prisma.io directly. Website-tagged signups fell from ~1,000 a week to under 10. Reintroduce the signal as a fallback `ref` instead of a UTM: the console already stores `ref` on signups (signup_first_ref / signup_last_ref) and PostHog does not treat it as a campaign parameter, so first-touch stays clean. It only fires when the visitor has no attribution at all, and never overrides a link that already carries some. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
Important Review skippedReview was skipped as selected files did not have any reviewable changes. ⚙️ Run configuration
You can disable this status message by setting the Use the checkbox below for a quick retry:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configuration
📒 Files selected for processing (4)
🚧 Files skipped from review as they are similar to previous changes (3)
Included review availability: This review used your included allowance. 3 included reviews remain after this review. Your included PR review attempts over the past 7 days set your current allowance at 5 reviews per hour. WalkthroughThe site and blog wrappers now provide a fallback ref callback to the shared UTM component. For eligible Console-bound links without captured attribution, the component adds a ChangesConsole link fallback refs
Priority: ⬇️ Low Estimated code review effort: 2 (Simple) | ~12 minutes Change: Bug fix Sequence Diagram(s)sequenceDiagram
participant Browser
participant UtmPersistence
participant syncFallbackRef
Browser->>UtmPersistence: Click Console-bound link
UtmPersistence->>syncFallbackRef: Apply ref when attribution is absent
syncFallbackRef-->>UtmPersistence: Return whether URL changed
UtmPersistence-->>Browser: Continue link handling
Merge Risk: ⚪ Minimal · up to Existing referral attribution remains unchanged when the fallback is applied; no concrete merge-blocking risk was identified in the reviewed changes. 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Summary
Stamp
ref=prisma.io/<page>on Console links for visitors who carry no attribution. This records the prisma.io page a signup converted from. It is not a source, it adds no UTM, and it never touches a visitor who arrived with real attribution.This agrees with the thread on #8141: UTMs attribute links to the site from outside, the site itself is not an acquisition channel, and
utm_source=websiteshould not come back. The question this PR answers is a different one: for the ~1,000 signups a week that convert from a prisma.io page without any campaign behind them, which page was it, and are they coming through the site at all or straight to the console and CLI? Since Aug 11 nothing records that.Three things support the change:
utm_source=websiteunder another name. Different parameter, different column, fires only when there is nothing else, and PostHog does not read it as a campaign.1. Why this is different from
utm_source=websiteutm_source=website&utm_medium=<page>(removed in #8141)ref=prisma.io/<page>(this PR)utm_source, a campaign parameterref, the console's referrer fieldref, or ad click ID, and the link carries none either$initial_utm_sourceand channel typewebsiteutm-sourceon the signup event, mixed in with real sourcessignup_last_refandsignup_first_ref, next to partner referrers (producthunt,laconsole.dev), prefixedprisma.ioA report that groups signups by
utm_sourcewill never show "website" again. A report that wants the conversion page readssignup_last_refinstead, and a report that only wants partners filters out theprisma.ioprefix.2. The conversion page is worth recording, and nothing else captures it
"80% website, 10% CLI" would tell us nothing about marketing, agreed. "1,000 untagged signups a week convert from a prisma.io page, 59% of them from the homepage, and the rest go straight to the console" tells us the site is in the funnel at all, which page converts, and what the Website → Signup step in the Growth Funnel dashboard should be counting. That is the question this field answers. Channel attribution stays with UTMs.
console:user_signed_upby week:utm_source=websitewww.prisma.ioas the person's initial referring domain, 42% had none or$direct. Week by week the referrer now finds 450 to 500 of what used to be ~1,000, and it is sliding. The site sendsReferrer-Policy: strict-origin-when-cross-origin, so the console only ever learns the origin, never which page.3. UTM forwarding is intact and audited, and the change is small and verified
Where we do and do not pass the original UTMs
Checked, per the ask in the thread:
apps/site,apps/blog, andpackages/uiis an anchor. There are nowindow.location,router.push, or form posts to the console, so the document-level capture-phase listener inUtmPersistencesees every click: nav, heroes, pricing plans, CTA bursts, and the/loginand/sign-upredirects.gclid,msclkid,fbclid, and friends) are forwarded to the console alongside UTMs, so Google auto-tagged paid traffic is attributed even with no UTM at all.utm_source=docson its own console links. By the same rule that removedwebsite, that should go too. Follow-up below.Where the change lives
packages/ui/src/lib/utm.ts:buildSiteRef(pathname)andsyncFallbackRef(url, ref), both pure and unit-tested.packages/ui/src/components/utm-persistence.tsx: a new optionalfallbackConsoleRefprop. In the click handler, if there is attribution it syncs as before. Otherwise, for console-bound links only, it stamps the fallback.apps/siteandapps/blogpassbuildSiteRef. Docs is not opted in.Relationship to #8141
Every change from #8141 stays in place:
utm_source=website/utm_source=blog/utm_source=sitedefaults stay removed. Nothing here writes autm_*value the visitor did not arrive with.utm_campaign=signup/loginfallback in the sharedWebNavigationbuilder is untouched.cta_clicktracking it wired in is untouched: it reads the renderedhref, not the rewritten one, same as for forwarded UTMs.The one scenario from that PR that changes on purpose: a clean visit no longer reaches
console.prisma.io/sign-upwith no params. It reaches it with?ref=prisma.ioor?ref=prisma.io/<page>. Every tagged scenario behaves exactly as before.Verified
@prisma-docs/ui,site, andblog.hrefat click time:/postgres, click Log in or Get Started:?ref=prisma.io%2Fpostgres, no UTMs./?utm_source=x&utm_campaign=launch-test, click: UTMs forwarded withfirst_utm_source=x, noref./pricinguntagged and click: stored UTMs still forwarded, noref./studio?ref=producthunt, click:ref=producthuntandfirst_ref=producthuntkept, not overwritten.Out of scope
utm_source=website. Reports keyed on it stay empty by design.Follow-ups
signup_last_reftostaging.stg_posthog__user_signupsand use it for the Website → Signup step and a "converting page" breakdown. Keep channel breakdowns onutm_source.signup_last_refshould exclude values starting withprisma.io.utm_source=docsdefault from docs console links and opt docs into the same fallback.🤖 Generated with Claude Code