Repository navigation
Track tutorial exit and play-now in GA4 - #79
adhocmedia wants to merge 3 commits into
Conversation
Fire two GA4 events so the newbie funnel can tell early exits from finishers: - exit_tutorial — when a player clicks Exit Tutorial - tutorial_complete_play — when they click Play MUME Now at the end (screen + modal) Both carry the current chapter. GA is already configured in the theme, so this only sends named events; nothing else changes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Reviewer's GuideUpdates the tutorial player to emit chapter-scoped GA4 events for early exits and completion-driven play actions, while maintaining navigation reliability and correctly handling completion state across chapters. Sequence diagram for tutorial funnel analytics eventssequenceDiagram
participant Player
participant TutorialPlayer
participant GA4 as window.gtag
participant Destination
alt Player exits before completion
Player->>TutorialPlayer: click Exit Tutorial
TutorialPlayer->>GA4: gtag('event', 'exit_tutorial', chapter)
TutorialPlayer->>Destination: navigate to Newcomers Hub
else Player selects Play MUME Now after completion
Player->>TutorialPlayer: click Play MUME Now
TutorialPlayer->>GA4: gtag('event', 'tutorial_complete_play', chapter)
TutorialPlayer->>Destination: navigate to Web Client
end
State diagram for tutorial completion trackingstateDiagram-v2
[*] --> InProgress
InProgress --> Completed: openModal()
InProgress --> InProgress: trackExit() / exit_tutorial
Completed --> Completed: trackExit() / no event
Completed --> InProgress: route.path changes
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've found 3 issues
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="docs/.vitepress/theme/components/TutorialPlayer.vue" line_range="711" />
<code_context>
</button>
- <a :href="withBase(NEWCOMERS_URL)" class="tut-action-btn tut-exit-btn" title="Exit Tutorial to Newcomers Hub" aria-label="Exit Tutorial">
+ <a :href="withBase(NEWCOMERS_URL)" class="tut-action-btn tut-exit-btn" title="Exit Tutorial to Newcomers Hub" aria-label="Exit Tutorial" @click="trackTutorial('exit_tutorial')">
<i class="fa fa-sign-out" aria-hidden="true"></i>
<span class="tut-btn-text">Exit</span>
</code_context>
<issue_to_address>
**Finishers counted as early exits**
When a player completes the final chapter and then clicks the always-visible Exit link, `trackTutorial('exit_tutorial')` fires regardless of completion state, so completed players are recorded as early exits and the skip-versus-finish metric is skewed.
Guard the exit event with completion state so it fires only before the tutorial is complete.
</issue_to_address>
### Comment 2
<location path="docs/.vitepress/theme/components/TutorialPlayer.vue" line_range="789" />
<code_context>
<div class="tut-end-actions">
- <a class="tut-enter" :href="withBase(BROWSER_PLAY_URL)">Play MUME Now (Web Client) →</a>
+ <a class="tut-enter" :href="withBase(BROWSER_PLAY_URL)" @click="trackTutorial('tutorial_complete_play')">Play MUME Now (Web Client) →</a>
<a class="tut-secondary-link" :href="withBase(NEWCOMERS_URL)">Explore Newcomers Guide</a>
<a class="tut-secondary-link" :href="withBase(PLAY_HUB_URL)">Back to Play Hub</a>
</code_context>
<issue_to_address>
**Completion play link never appears**
When a player expects to use the end-screen Play MUME Now link, `renderStepLog()` and the step handlers never produce an `end` item, so the `b.kind === 'end'` branch never renders the link and its `tutorial_complete_play` handler cannot fire; the completion click goes untracked.
Add an `end` item when the final chapter is completed so the link renders and its handler can fire.
</issue_to_address>
### Comment 3
<location path="docs/.vitepress/theme/components/TutorialPlayer.vue" line_range="114" />
<code_context>
+function trackTutorial(name: string) {
+ try {
+ ;(window as any).gtag?.('event', name, { event_category: 'tutorial', chapter: chapterNum.value })
+ } catch { /* analytics is best-effort, never block navigation */ }
+}
+
</code_context>
<issue_to_address>
**Analytics failures go unnoticed**
When `window.gtag` throws while a player clicks one of the tracked links, `trackTutorial` suppresses the exception and continues navigation, so the event is dropped with no diagnostic for operators; the tutorial funnel is silently undercounted.
Report the caught error through a non-blocking diagnostic while continuing navigation.
</issue_to_address>Sourcery assessment
Needs a human reviewer. 3 findings to address first, and clicking either link sends the event name and current chapter number to the existing GA4 property, where those records can remain after a revert; reverting stops future events but does not remove past ones. The impact is limited to bounded analytics data, not a change to navigation or game behavior.
Blocking findings: docs/.vitepress/theme/components/TutorialPlayer.vue:711, docs/.vitepress/theme/components/TutorialPlayer.vue:789, docs/.vitepress/theme/components/TutorialPlayer.vue:114
|
|
||
| <div class="tut-end-actions"> | ||
| <a class="tut-enter" :href="withBase(BROWSER_PLAY_URL)">Play MUME Now (Web Client) →</a> | ||
| <a class="tut-enter" :href="withBase(BROWSER_PLAY_URL)" @click="trackTutorial('tutorial_complete_play')">Play MUME Now (Web Client) →</a> |
There was a problem hiding this comment.
🟡 Medium · Completion play link never appears
When a player expects to use the end-screen Play MUME Now link, renderStepLog() and the step handlers never produce an end item, so the b.kind === 'end' branch never renders the link and its tutorial_complete_play handler cannot fire; the completion click goes untracked.
Add an end item when the final chapter is completed so the link renders and its handler can fire.
Prompt for AI agents
In `docs/.vitepress/theme/components/TutorialPlayer.vue` at line 789:
**Completion play link never appears**
When a player expects to use the end-screen Play MUME Now link, `renderStepLog()` and the step handlers never produce an `end` item, so the `b.kind === 'end'` branch never renders the link and its `tutorial_complete_play` handler cannot fire; the completion click goes untracked.
Add an `end` item when the final chapter is completed so the link renders and its handler can fire.- Guard exit_tutorial behind a tutorialCompleted flag (set when the end-of-tutorial modal opens), so finishers who later click Exit are not counted as early exits. - Drop the @click on the dead end-screen link (the 'end' beat is never generated, so that branch never renders); completion is tracked on the modal's Play button. - Log caught analytics errors via console.debug instead of swallowing them. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Thanks, addressed all three:
|
|
@sourcery-ai review |
There was a problem hiding this comment.
Hey - I've found 2 issues
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="docs/.vitepress/theme/components/TutorialPlayer.vue" line_range="98" />
<code_context>
const isSheetOpen = ref(false)
const isExpanded = ref(false)
const isModalOpen = ref(false)
+const tutorialCompleted = ref(false)
const activeModalImage = ref<{ src: string; alt: string } | null>(null)
</code_context>
<issue_to_address>
**Retake exits go uncounted**
When a player completes the tutorial, navigates to another chapter, and clicks Exit, the route watcher rerenders the chapter without resetting `tutorialCompleted`, so `trackExit()` suppresses `exit_tutorial` and GA4 misses the retake exit.
Reset `tutorialCompleted` when the route watcher loads another chapter.
Also at `docs/.vitepress/theme/components/TutorialPlayer.vue:105`.
</issue_to_address>
### Comment 2
<location path="docs/.vitepress/theme/components/TutorialPlayer.vue" line_range="117" />
<code_context>
+// the theme; this only sends a named signal with the chapter they were on.
+function trackTutorial(name: string) {
+ try {
+ ;(window as any).gtag?.('event', name, { event_category: 'tutorial', chapter: chapterNum.value })
+ } catch (err) {
+ // Analytics is best-effort and must never block navigation; surface it quietly.
</code_context>
<issue_to_address>
**Navigation drops queued tutorial events**
When a player clicks Exit or Play before the asynchronously loaded GA script has processed the queued event, `trackTutorial` only queues the event in the page's in-memory `dataLayer`, while the Exit and Play anchors immediately navigate away. If the async GA script has not consumed and sent the queued event, unloading the page discards it and GA4 misses the conversion.
Send the event using a navigation-safe mechanism, or wait for GA's event callback before allowing the anchor navigation.
Also at `docs/.vitepress/theme/components/TutorialPlayer.vue:724`, `docs/.vitepress/theme/components/TutorialPlayer.vue:904`.
</issue_to_address>Sourcery assessment
Needs a human reviewer. 2 findings to address first, and each Exit or Play Now click sends a chapter-tagged event to GA4, so an incorrect event or chapter can leave misleading analytics records that reverting the code will not retract. The impact is limited to those tracking records; this adds no user-identifying data in the diff.
Blocking findings: docs/.vitepress/theme/components/TutorialPlayer.vue:98, docs/.vitepress/theme/components/TutorialPlayer.vue:117
| const isSheetOpen = ref(false) | ||
| const isExpanded = ref(false) | ||
| const isModalOpen = ref(false) | ||
| const tutorialCompleted = ref(false) |
There was a problem hiding this comment.
🟡 Medium · Retake exits go uncounted
When a player completes the tutorial, navigates to another chapter, and clicks Exit, the route watcher rerenders the chapter without resetting tutorialCompleted, so trackExit() suppresses exit_tutorial and GA4 misses the retake exit.
Reset tutorialCompleted when the route watcher loads another chapter.
Also at docs/.vitepress/theme/components/TutorialPlayer.vue:105.
Prompt for AI agents
In `docs/.vitepress/theme/components/TutorialPlayer.vue` at line 98:
**Retake exits go uncounted**
When a player completes the tutorial, navigates to another chapter, and clicks Exit, the route watcher rerenders the chapter without resetting `tutorialCompleted`, so `trackExit()` suppresses `exit_tutorial` and GA4 misses the retake exit.
Reset `tutorialCompleted` when the route watcher loads another chapter.
Also at `docs/.vitepress/theme/components/TutorialPlayer.vue:105`.| // the theme; this only sends a named signal with the chapter they were on. | ||
| function trackTutorial(name: string) { | ||
| try { | ||
| ;(window as any).gtag?.('event', name, { event_category: 'tutorial', chapter: chapterNum.value }) |
There was a problem hiding this comment.
🟡 Medium · Navigation drops queued tutorial events
When a player clicks Exit or Play before the asynchronously loaded GA script has processed the queued event, trackTutorial only queues the event in the page's in-memory dataLayer, while the Exit and Play anchors immediately navigate away. If the async GA script has not consumed and sent the queued event, unloading the page discards it and GA4 misses the conversion.
Send the event using a navigation-safe mechanism, or wait for GA's event callback before allowing the anchor navigation.
Also at docs/.vitepress/theme/components/TutorialPlayer.vue:724, docs/.vitepress/theme/components/TutorialPlayer.vue:904.
Prompt for AI agents
In `docs/.vitepress/theme/components/TutorialPlayer.vue` at line 117:
**Navigation drops queued tutorial events**
When a player clicks Exit or Play before the asynchronously loaded GA script has processed the queued event, `trackTutorial` only queues the event in the page's in-memory `dataLayer`, while the Exit and Play anchors immediately navigate away. If the async GA script has not consumed and sent the queued event, unloading the page discards it and GA4 misses the conversion.
Send the event using a navigation-safe mechanism, or wait for GA's event callback before allowing the anchor navigation.
Also at `docs/.vitepress/theme/components/TutorialPlayer.vue:724`, `docs/.vitepress/theme/components/TutorialPlayer.vue:904`.Chapter navigation is SPA (router.go), so the component is not remounted and tutorialCompleted would persist. Reset it in the route watcher so a retake-then-exit is still counted as an exit. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Round 2, thanks:
|
|
@sourcery-ai review |
There was a problem hiding this comment.
Hey - I've reviewed your changes and they look great!
Sourcery assessment
Needs a human reviewer. If the events fire at the wrong time, GA4 will retain a bounded set of misclassified tutorial events; reverting stops new events but does not remove the historical data. No user-facing navigation or other behavior changes.
Adds two GA4 events on the interactive tutorial so we can measure the newbie funnel properly.
Events
exit_tutorial— fires when a player clicks Exit Tutorial (left early).tutorial_complete_play— fires on Play MUME Now at the end (both the end screen and the completion modal).Both include a
chapterparameter (which chapter they were on). GA4 is already set up in the theme (G-LL4RX9KM6Q, consent-aware), so this only sends named events via the existingwindow.gtag; no base analytics or config changes, and navigation is unaffected (best-effort, wrapped in try/catch).After merge/deploy, mark
exit_tutorialandtutorial_complete_playas Key events in GA4 to track them as conversions. The ratio of the two gives the skip-vs-finish rate.🤖 Generated with Claude Code
Summary by Sourcery
Add consent-compatible GA4 funnel tracking for tutorial exits and transitions into gameplay.
New Features:
Enhancements: