Skip to content

Commit 9ba5562

Browse files
committed
chore: simplify Google Analytics to standard implementation
- Remove Consent Mode v2 implementation - Remove URL passthrough and cookieless tracking features - Switch to Google's standard out-of-the-box gtag.js pattern - Maintain consent-based loading (scripts only load after user consent) Rationale: The standard OoTB implementation is more stable and complies with consent requirements. The cookieless tracking wasn't working properly, and the effort to get it working isn't worth the added complexity.
1 parent ae9f3fe commit 9ba5562

File tree

1 file changed

+24
-110
lines changed

1 file changed

+24
-110
lines changed

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

Lines changed: 24 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -8,146 +8,60 @@ import { hasConsent, onConsentChange } from "@/lib/analytics/consent-manager"
88
const GTM_ID = "AW-17391954825"
99

1010
/**
11-
* Google Analytics Provider with Consent Mode v2
12-
* Implements cookieless pings and advanced consent management
11+
* Google Analytics Provider
12+
* Implements Google's standard gtag.js loading pattern
1313
*/
1414
export function GoogleAnalyticsProvider({ children }: { children: React.ReactNode }) {
1515
const [shouldLoad, setShouldLoad] = useState(false)
1616

1717
useEffect(() => {
18-
// Initialize consent defaults BEFORE loading gtag.js (required for Consent Mode v2)
19-
initializeConsentDefaults()
20-
2118
// Check initial consent status
2219
if (hasConsent()) {
2320
setShouldLoad(true)
24-
updateConsentGranted()
2521
}
2622

2723
// Listen for consent changes
2824
const unsubscribe = onConsentChange((consented) => {
29-
if (consented) {
30-
if (!shouldLoad) {
31-
setShouldLoad(true)
32-
}
33-
updateConsentGranted()
34-
} else {
35-
updateConsentDenied()
25+
if (consented && !shouldLoad) {
26+
setShouldLoad(true)
3627
}
3728
})
3829

3930
return unsubscribe
40-
// eslint-disable-next-line react-hooks/exhaustive-deps -- shouldLoad intentionally omitted to prevent re-initialization loop
41-
}, [])
31+
}, [shouldLoad])
4232

43-
const initializeConsentDefaults = () => {
44-
// Set up consent defaults before gtag loads (Consent Mode v2 requirement)
33+
useEffect(() => {
34+
// Initialize dataLayer as early as possible (Google's recommended pattern)
4535
if (typeof window !== "undefined") {
4636
window.dataLayer = window.dataLayer || []
47-
window.gtag = function (...args: GtagArgs) {
48-
window.dataLayer.push(args)
49-
}
50-
51-
// Set default consent state to 'denied' with cookieless pings enabled
52-
window.gtag("consent", "default", {
53-
ad_storage: "denied",
54-
ad_user_data: "denied",
55-
ad_personalization: "denied",
56-
analytics_storage: "denied",
57-
functionality_storage: "denied",
58-
personalization_storage: "denied",
59-
security_storage: "granted", // Always granted for security
60-
wait_for_update: 500, // Wait 500ms for consent before sending data
61-
})
62-
63-
// Enable cookieless pings for Google Ads
64-
window.gtag("set", "url_passthrough", true)
65-
}
66-
}
67-
68-
const updateConsentGranted = () => {
69-
// User accepted cookies - update consent to granted
70-
if (typeof window !== "undefined" && window.gtag) {
71-
window.gtag("consent", "update", {
72-
ad_storage: "granted",
73-
ad_user_data: "granted",
74-
ad_personalization: "granted",
75-
analytics_storage: "granted",
76-
functionality_storage: "granted",
77-
personalization_storage: "granted",
78-
})
79-
}
80-
}
81-
82-
const updateConsentDenied = () => {
83-
// User declined cookies - keep consent denied (cookieless pings still work)
84-
if (typeof window !== "undefined" && window.gtag) {
85-
window.gtag("consent", "update", {
86-
ad_storage: "denied",
87-
ad_user_data: "denied",
88-
ad_personalization: "denied",
89-
analytics_storage: "denied",
90-
functionality_storage: "denied",
91-
personalization_storage: "denied",
92-
})
9337
}
94-
}
95-
96-
// Always render scripts (Consent Mode v2 needs gtag loaded even without consent)
97-
// Cookieless pings will work with denied consent
38+
}, [])
9839

9940
return (
10041
<>
101-
{/* Google tag (gtag.js) - Loads immediately for Consent Mode v2 */}
102-
<Script
103-
src={`https://www.googletagmanager.com/gtag/js?id=${GTM_ID}`}
104-
strategy="afterInteractive"
105-
onLoad={() => {
106-
// Initialize gtag config after script loads
107-
if (typeof window !== "undefined" && window.gtag) {
108-
window.gtag("js", new Date())
109-
window.gtag("config", GTM_ID)
110-
}
111-
}}
112-
/>
42+
{shouldLoad && (
43+
<>
44+
{/* Google tag (gtag.js) */}
45+
<Script src={`https://www.googletagmanager.com/gtag/js?id=${GTM_ID}`} strategy="afterInteractive" />
46+
<Script id="google-analytics" strategy="afterInteractive">
47+
{`
48+
window.dataLayer = window.dataLayer || [];
49+
function gtag(){dataLayer.push(arguments);}
50+
gtag('js', new Date());
51+
gtag('config', '${GTM_ID}');
52+
`}
53+
</Script>
54+
</>
55+
)}
11356
{children}
11457
</>
11558
)
11659
}
11760

118-
// Type definitions for Google Analytics with Consent Mode v2
119-
type ConsentState = "granted" | "denied"
120-
121-
interface ConsentParams {
122-
ad_storage?: ConsentState
123-
ad_user_data?: ConsentState
124-
ad_personalization?: ConsentState
125-
analytics_storage?: ConsentState
126-
functionality_storage?: ConsentState
127-
personalization_storage?: ConsentState
128-
security_storage?: ConsentState
129-
wait_for_update?: number
130-
}
131-
132-
type GtagArgs =
133-
| ["js", Date]
134-
| ["config", string, GtagConfig?]
135-
| ["event", string, GtagEventParameters?]
136-
| ["consent", "default" | "update", ConsentParams]
137-
| ["set", string, unknown]
138-
139-
interface GtagConfig {
140-
[key: string]: unknown
141-
}
142-
143-
interface GtagEventParameters {
144-
[key: string]: unknown
145-
}
146-
14761
// Declare global types for TypeScript
14862
declare global {
14963
interface Window {
150-
dataLayer: GtagArgs[]
151-
gtag: (...args: GtagArgs) => void
64+
dataLayer: unknown[]
65+
gtag: (...args: unknown[]) => void
15266
}
15367
}

0 commit comments

Comments
 (0)