Skip to content

Conversation

@roomote
Copy link

@roomote roomote bot commented Nov 4, 2025

Summary

This PR adds the pattern to Google Ads conversion tracking to prevent lost conversions during navigation.

Context

The Slack analysis claimed that Google Ads conversion tracking wasn't working due to missing gtag.js setup and Consent Mode v2 configuration. However, upon investigation, the existing implementation was already comprehensive and correct:

✅ Google tag (gtag.js) is loaded via GoogleAnalyticsProvider
✅ Consent Mode v2 is properly configured with all required fields
✅ Cookie consent properly updates ad consent on accept
✅ Conversion tracking is implemented with correct send_to parameter

The Actual Issue

The only valid concern was the missing event_callback pattern. Without it, when users click CTA buttons, the page navigation can occur before the conversion tracking network request completes, resulting in lost conversions.

Changes

Modified Files

  • apps/web-roo-code/src/lib/analytics/google-ads.ts

    • Added optional targetUrl parameter to trackGoogleAdsConversion()
    • Implemented event_callback to handle navigation after tracking completes
    • Added 1-second fallback timeout for reliability
    • Added comprehensive JSDoc documentation
  • apps/web-roo-code/src/app/reviewer/ReviewerContent.tsx

    • Updated both CTA button click handlers to prevent default navigation
    • Pass target URL to tracking function for callback-based navigation
  • apps/web-roo-code/src/app/pr-fixer/PrFixerContent.tsx

    • Applied same pattern to PR Fixer CTA buttons for consistency

Benefits

  • ✅ Ensures conversion tracking completes before navigation
  • ✅ Prevents lost conversions on fast clicks
  • ✅ Includes fallback timeout for reliability
  • ✅ Follows Google's recommended best practices
  • ✅ Maintains existing Consent Mode v2 implementation

Testing

The implementation follows Google's official recommendation for click conversion tracking with event callbacks.


Important

Adds event_callback pattern to Google Ads conversion tracking to ensure conversions are tracked before navigation, preventing lost conversions.

  • Behavior:
    • Adds event_callback pattern to trackGoogleAdsConversion() in google-ads.ts to ensure conversion tracking completes before navigation.
    • Implements 1-second fallback timeout in trackGoogleAdsConversion() for reliability.
  • Files Modified:
    • ReviewerContent.tsx: Updates CTA button click handlers to prevent default navigation and use callback-based navigation.
    • PrFixerContent.tsx: Applies the same pattern to CTA buttons for consistency.
  • Benefits:
    • Prevents lost conversions on fast clicks.
    • Follows Google's recommended best practices for conversion tracking.
    • Maintains existing Consent Mode v2 implementation.

This description was created by Ellipsis for e532fad. You can customize this summary. It will automatically update as commits are pushed.

- Add event_callback to trackGoogleAdsConversion() to ensure conversion ping completes before navigation
- Update CTA button handlers to prevent default navigation and pass target URL
- Add fallback timeout for reliability in case callback does not fire
- Improve documentation with usage examples
- Apply same event_callback pattern to PR Fixer CTA buttons
- Fixes TypeScript errors from updated trackGoogleAdsConversion signature
@roomote roomote bot requested review from cte, jr and mrubens as code owners November 4, 2025 08:03
@dosubot dosubot bot added size:M This PR changes 30-99 lines, ignoring generated files. bug Something isn't working documentation Improvements or additions to documentation labels Nov 4, 2025
@roomote
Copy link
Author

roomote bot commented Nov 4, 2025

See this task on Roo Code Cloud

Review completed. Found 5 issues that need attention:

  • Fix race condition where callback executes twice in trackGoogleAdsConversion()
  • Preserve new tab behavior in ReviewerContent.tsx (line 130-133)
  • Preserve new tab behavior in ReviewerContent.tsx (line 287-290)
  • Preserve new tab behavior in PrFixerContent.tsx (line 115-118)
  • Preserve new tab behavior in PrFixerContent.tsx (line 231-234)

Mention @roomote in a comment to trigger your PR Fixer agent and make changes to this pull request.

@github-actions
Copy link

github-actions bot commented Nov 4, 2025

🚀 Preview deployed!

Your changes have been deployed to Vercel:

Preview URL: https://roo-code-website-awxpoafdf-roo-code.vercel.app

This preview will be updated automatically when you push new commits to this PR.

Comment on lines +19 to 42
export function trackGoogleAdsConversion(targetUrl?: string) {
if (typeof window !== "undefined" && window.gtag) {
// Callback to handle navigation after conversion tracking
const callback = () => {
if (targetUrl) {
window.location.href = targetUrl
}
}

window.gtag("event", "conversion", {
send_to: "AW-17391954825/VtOZCJe_77MbEInXkOVA",
value: 10.0,
currency: "USD",
event_callback: callback,
})

// Fallback timeout in case event_callback doesn't fire (network issues, etc.)
// This ensures navigation still happens even if tracking fails
setTimeout(callback, 1000)
} else if (targetUrl) {
// If gtag is not available, navigate immediately
window.location.href = targetUrl
}
}
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The callback can execute twice: once from event_callback and once from setTimeout. If the tracking completes before 1 second (the common case), both navigation attempts will fire. This should use a flag to ensure the callback only executes once.

Suggested change
export function trackGoogleAdsConversion(targetUrl?: string) {
if (typeof window !== "undefined" && window.gtag) {
// Callback to handle navigation after conversion tracking
const callback = () => {
if (targetUrl) {
window.location.href = targetUrl
}
}
window.gtag("event", "conversion", {
send_to: "AW-17391954825/VtOZCJe_77MbEInXkOVA",
value: 10.0,
currency: "USD",
event_callback: callback,
})
// Fallback timeout in case event_callback doesn't fire (network issues, etc.)
// This ensures navigation still happens even if tracking fails
setTimeout(callback, 1000)
} else if (targetUrl) {
// If gtag is not available, navigate immediately
window.location.href = targetUrl
}
}
export function trackGoogleAdsConversion(targetUrl?: string) {
if (typeof window !== "undefined" && window.gtag) {
let hasNavigated = false
// Callback to handle navigation after conversion tracking
const callback = () => {
if (!hasNavigated && targetUrl) {
hasNavigated = true
window.location.href = targetUrl
}
}
window.gtag("event", "conversion", {
send_to: "AW-17391954825/VtOZCJe_77MbEInXkOVA",
value: 10.0,
currency: "USD",
event_callback: callback,
})
// Fallback timeout in case event_callback doesn't fire (network issues, etc.)
// This ensures navigation still happens even if tracking fails
setTimeout(callback, 1000)
} else if (targetUrl) {
// If gtag is not available, navigate immediately
window.location.href = targetUrl
}
}

Fix it with Roo Code or mention @roomote and request a fix.

Comment on lines +130 to +133
onClick={(e) => {
e.preventDefault()
trackGoogleAdsConversion(EXTERNAL_LINKS.CLOUD_APP_SIGNUP_PRO)
}}
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This changes the link behavior from opening in a new tab to navigating the current tab. The anchor has target="_blank" but e.preventDefault() + window.location.href overrides this, breaking the original user experience of keeping the marketing site open while opening the signup page in a new tab. Use window.open(targetUrl, '_blank') to preserve the new tab behavior.

Fix it with Roo Code or mention @roomote and request a fix.

Comment on lines +287 to +290
onClick={(e) => {
e.preventDefault()
trackGoogleAdsConversion(EXTERNAL_LINKS.CLOUD_APP_SIGNUP_PRO)
}}
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same issue: this changes the link behavior from opening in a new tab to navigating the current tab. The anchor has target="_blank" but e.preventDefault() + window.location.href overrides this. Use window.open(targetUrl, '_blank') to preserve the new tab behavior.

Fix it with Roo Code or mention @roomote and request a fix.

Comment on lines +115 to +118
onClick={(e) => {
e.preventDefault()
trackGoogleAdsConversion(EXTERNAL_LINKS.CLOUD_APP_SIGNUP_PRO)
}}
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same issue: this changes the link behavior from opening in a new tab to navigating the current tab. The anchor has target="_blank" but e.preventDefault() + window.location.href overrides this. Use window.open(targetUrl, '_blank') to preserve the new tab behavior.

Fix it with Roo Code or mention @roomote and request a fix.

Comment on lines +231 to +234
onClick={(e) => {
e.preventDefault()
trackGoogleAdsConversion(EXTERNAL_LINKS.CLOUD_APP_SIGNUP_PRO)
}}
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same issue: this changes the link behavior from opening in a new tab to navigating the current tab. The anchor has target="_blank" but e.preventDefault() + window.location.href overrides this. Use window.open(targetUrl, '_blank') to preserve the new tab behavior.

Fix it with Roo Code or mention @roomote and request a fix.

@hannesrudolph hannesrudolph added the Issue/PR - Triage New issue. Needs quick review to confirm validity and assign labels. label Nov 4, 2025
@dleffel dleffel closed this Nov 4, 2025
@github-project-automation github-project-automation bot moved this from New to Done in Roo Code Roadmap Nov 4, 2025
@github-project-automation github-project-automation bot moved this from Triage to Done in Roo Code Roadmap Nov 4, 2025
@dleffel dleffel deleted the fix/google-ads-conversion-callback branch November 4, 2025 14:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working documentation Improvements or additions to documentation Issue/PR - Triage New issue. Needs quick review to confirm validity and assign labels. size:M This PR changes 30-99 lines, ignoring generated files.

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

4 participants