Repository navigation
Track tutorial exit and play-now in GA4 #79
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -95,16 +95,38 @@ const entry = ref('') | |
| 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) | ||
|
|
||
| function openModal() { | ||
| isModalOpen.value = true | ||
| // Reaching the end-of-tutorial modal means the player finished, so a later Exit | ||
| // click should not be counted as an early exit. | ||
| tutorialCompleted.value = true | ||
| } | ||
|
|
||
| function closeModal() { | ||
| isModalOpen.value = false | ||
| } | ||
|
|
||
| // Fire a GA4 event when a player leaves the tutorial early (exit_tutorial) or | ||
| // finishes and heads to the game (tutorial_complete_play). GA is already set up in | ||
| // 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 }) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 Medium · Navigation drops queued tutorial events When a player clicks Exit or Play before the asynchronously loaded GA script has processed the queued event, Send the event using a navigation-safe mechanism, or wait for GA's event callback before allowing the anchor navigation. Also at Prompt for AI agentsIn `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`. |
||
| } catch (err) { | ||
| // Analytics is best-effort and must never block navigation; surface it quietly. | ||
| console.debug('tutorial analytics event failed', name, err) | ||
| } | ||
| } | ||
|
|
||
| // The Exit control is always visible, including after completion, so only count a | ||
| // click as an early exit when the player has not reached the end-of-tutorial screen. | ||
| function trackExit() { | ||
| if (!tutorialCompleted.value) trackTutorial('exit_tutorial') | ||
| } | ||
|
|
||
| function openImageModal(src: string, alt = '') { | ||
| activeModalImage.value = { src, alt } | ||
| } | ||
|
|
@@ -610,6 +632,9 @@ function submit() { | |
| } | ||
|
|
||
| watch(() => route.path, () => { | ||
| // Navigation here is SPA, so this component is not remounted between chapters. | ||
| // Clear the completion flag on each chapter so a retake-then-exit is counted. | ||
| tutorialCompleted.value = false | ||
| renderStepLog() | ||
| }, { immediate: true }) | ||
|
|
||
|
|
@@ -699,7 +724,7 @@ onUnmounted(() => { | |
| <span class="tut-btn-text">{{ isExpanded ? 'Shrink' : 'Full' }}</span> | ||
| </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="trackExit()"> | ||
| <i class="fa fa-sign-out" aria-hidden="true"></i> | ||
| <span class="tut-btn-text">Exit</span> | ||
| </a> | ||
|
|
@@ -879,7 +904,7 @@ onUnmounted(() => { | |
| </p> | ||
|
|
||
| <div class="tut-modal-buttons"> | ||
| <a class="tut-modal-btn tut-btn-primary" :href="withBase(BROWSER_PLAY_URL)"> | ||
| <a class="tut-modal-btn tut-btn-primary" :href="withBase(BROWSER_PLAY_URL)" @click="trackTutorial('tutorial_complete_play')"> | ||
| <i class="fa fa-gamepad" aria-hidden="true"></i> Play MUME Now (Web Client) → | ||
| </a> | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🟡 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, sotrackExit()suppressesexit_tutorialand GA4 misses the retake exit.Reset
tutorialCompletedwhen the route watcher loads another chapter.Also at
docs/.vitepress/theme/components/TutorialPlayer.vue:105.Prompt for AI agents