Skip to content
This repository was archived by the owner on May 15, 2026. It is now read-only.

Commit bfa4c67

Browse files
committed
fix: add attribution tracking and correct blog event names
- Fix $pageview to include $referrer, $referring_domain, and UTM params - Track previous URL for SPA navigation referrer attribution - Rename events to blog_index_view and blog_post_view (per spec) - Add publish_time_pt property to blog_post_view - Add trackBlogSubstackClick function for use with MKT-72
1 parent bd1b3ad commit bfa4c67

3 files changed

Lines changed: 81 additions & 10 deletions

File tree

apps/web-roo-code/src/components/providers/posthog-provider.tsx

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,85 @@
33
import { usePathname, useSearchParams } from "next/navigation"
44
import posthog from "posthog-js"
55
import { PostHogProvider as OriginalPostHogProvider } from "posthog-js/react"
6-
import { useEffect, Suspense } from "react"
6+
import { useEffect, useRef, Suspense } from "react"
77
import { hasConsent } from "@/lib/analytics/consent-manager"
88

9+
/**
10+
* Extract referring domain from a URL string
11+
*/
12+
function getReferringDomain(referrer: string): string {
13+
if (!referrer) return ""
14+
try {
15+
const url = new URL(referrer)
16+
return url.hostname
17+
} catch {
18+
return ""
19+
}
20+
}
21+
22+
/**
23+
* Get UTM parameters from current URL search params
24+
*/
25+
function getUtmParams(searchParams: URLSearchParams | null): Record<string, string> {
26+
const utmKeys = ["utm_source", "utm_medium", "utm_campaign", "utm_term", "utm_content"]
27+
const utmParams: Record<string, string> = {}
28+
29+
if (searchParams) {
30+
for (const key of utmKeys) {
31+
const value = searchParams.get(key)
32+
if (value) {
33+
utmParams[key] = value
34+
}
35+
}
36+
}
37+
38+
return utmParams
39+
}
40+
941
function PageViewTracker() {
1042
const pathname = usePathname()
1143
const searchParams = useSearchParams()
44+
// Track previous URL for SPA navigation referrer
45+
const previousUrl = useRef<string | null>(null)
46+
// Store original document.referrer for first page load
47+
const initialReferrer = useRef<string | null>(null)
1248

13-
// Track page views
49+
// Capture initial referrer on mount
50+
useEffect(() => {
51+
if (typeof window !== "undefined" && initialReferrer.current === null) {
52+
initialReferrer.current = document.referrer || ""
53+
}
54+
}, [])
55+
56+
// Track page views with proper attribution
1457
useEffect(() => {
1558
if (pathname && process.env.NEXT_PUBLIC_POSTHOG_KEY) {
1659
let url = window.location.origin + pathname
1760
if (searchParams && searchParams.toString()) {
1861
url = url + `?${searchParams.toString()}`
1962
}
63+
64+
// Determine the referrer:
65+
// - For first pageview: use document.referrer (external referrer)
66+
// - For SPA navigations: use previous URL within the site
67+
const referrer = previousUrl.current || initialReferrer.current || ""
68+
const referringDomain = getReferringDomain(referrer)
69+
70+
// Collect UTM parameters
71+
const utmParams = getUtmParams(searchParams)
72+
2073
posthog.capture("$pageview", {
2174
$current_url: url,
75+
$referrer: referrer,
76+
$referring_domain: referringDomain,
77+
...utmParams,
2278
})
79+
80+
// Update previous URL for next navigation
81+
previousUrl.current = url
2382
}
2483
// eslint-disable-next-line react-hooks/exhaustive-deps
25-
}, [pathname, searchParams.toString()])
84+
}, [pathname, searchParams?.toString()])
2685

2786
return null
2887
}

apps/web-roo-code/src/lib/blog/analytics.ts

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,8 @@ import type { BlogPost } from "./types"
1515
export function trackBlogIndexView(postCount: number): void {
1616
if (typeof window === "undefined" || !posthog.__loaded) return
1717

18-
posthog.capture("blog_index_viewed", {
18+
posthog.capture("blog_index_view", {
1919
post_count: postCount,
20-
page_type: "blog_index",
2120
})
2221
}
2322

@@ -28,12 +27,24 @@ export function trackBlogIndexView(postCount: number): void {
2827
export function trackBlogPostView(post: BlogPost): void {
2928
if (typeof window === "undefined" || !posthog.__loaded) return
3029

31-
posthog.capture("blog_post_viewed", {
32-
post_slug: post.slug,
33-
post_title: post.title,
34-
post_tags: post.tags,
30+
posthog.capture("blog_post_view", {
31+
slug: post.slug,
32+
title: post.title,
33+
tags: post.tags,
3534
publish_date: post.publish_date,
36-
page_type: "blog_post",
35+
publish_time_pt: post.publish_time_pt,
36+
})
37+
}
38+
39+
/**
40+
* Track Substack subscribe click
41+
* Called when user clicks the Substack subscribe link
42+
*/
43+
export function trackBlogSubstackClick(source: "footer" | "blog_index" | "blog_post"): void {
44+
if (typeof window === "undefined" || !posthog.__loaded) return
45+
46+
posthog.capture("blog_substack_click", {
47+
source,
3748
})
3849
}
3950

apps/web-roo-code/src/lib/blog/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,5 @@ export {
5353
trackBlogPostShare,
5454
trackBlogPostCTAClick,
5555
trackBlogPostTimeSpent,
56+
trackBlogSubstackClick,
5657
} from "./analytics"

0 commit comments

Comments
 (0)