Skip to content

Commit 5e0bf5d

Browse files
committed
chore(product tours): move tour event names to constants
1 parent a3cc497 commit 5e0bf5d

File tree

5 files changed

+133
-83
lines changed

5 files changed

+133
-83
lines changed

.changeset/true-chairs-grow.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'posthog-js': patch
3+
---
4+
5+
move tour event names to constants

packages/browser/src/extensions/product-tours/product-tours.tsx

Lines changed: 82 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,16 @@ import {
55
ProductTourBannerConfig,
66
ProductTourCallback,
77
ProductTourDismissReason,
8+
ProductTourEventName,
9+
ProductTourEventProperties,
810
ProductTourRenderReason,
911
ProductTourStepButton,
1012
ShowTourOptions,
1113
} from '../../posthog-product-tours-types'
1214
import { SurveyEventName, SurveyEventProperties } from '../../posthog-surveys-types'
1315
import {
1416
addProductTourCSSVariablesToElement,
17+
ElementFindResult,
1518
findStepElement,
1619
getElementMetadata,
1720
getProductTourStylesheet,
@@ -445,11 +448,11 @@ export class ProductTourManager {
445448
const rendered = this._renderCurrentStep()
446449

447450
if (rendered) {
448-
this._captureEvent('product tour shown', {
449-
$product_tour_id: tour.id,
450-
$product_tour_name: tour.name,
451-
$product_tour_iteration: tour.current_iteration || 1,
452-
$product_tour_render_reason: renderReason,
451+
this._captureEvent(ProductTourEventName.SHOWN, {
452+
[ProductTourEventProperties.TOUR_ID]: tour.id,
453+
[ProductTourEventProperties.TOUR_NAME]: tour.name,
454+
[ProductTourEventProperties.TOUR_ITERATION]: tour.current_iteration || 1,
455+
[ProductTourEventProperties.TOUR_RENDER_REASON]: renderReason,
453456
})
454457

455458
if (!this._isPreviewMode) {
@@ -497,10 +500,10 @@ export class ProductTourManager {
497500

498501
const currentStep = this._activeTour.steps[this._currentStepIndex]
499502

500-
this._captureEvent('product tour step completed', {
501-
$product_tour_id: this._activeTour.id,
502-
$product_tour_step_id: currentStep.id,
503-
$product_tour_step_order: this._currentStepIndex,
503+
this._captureEvent(ProductTourEventName.STEP_COMPLETED, {
504+
[ProductTourEventProperties.TOUR_ID]: this._activeTour.id,
505+
[ProductTourEventProperties.TOUR_STEP_ID]: currentStep.id,
506+
[ProductTourEventProperties.TOUR_STEP_ORDER]: this._currentStepIndex,
504507
})
505508

506509
if (this._currentStepIndex < this._activeTour.steps.length - 1) {
@@ -527,11 +530,11 @@ export class ProductTourManager {
527530

528531
const currentStep = this._activeTour.steps[this._currentStepIndex]
529532

530-
this._captureEvent('product tour dismissed', {
531-
$product_tour_id: this._activeTour.id,
532-
$product_tour_step_id: currentStep.id,
533-
$product_tour_step_order: this._currentStepIndex,
534-
$product_tour_dismiss_reason: reason,
533+
this._captureEvent(ProductTourEventName.DISMISSED, {
534+
[ProductTourEventProperties.TOUR_ID]: this._activeTour.id,
535+
[ProductTourEventProperties.TOUR_STEP_ID]: currentStep.id,
536+
[ProductTourEventProperties.TOUR_STEP_ORDER]: this._currentStepIndex,
537+
[ProductTourEventProperties.TOUR_DISMISS_REASON]: reason,
535538
})
536539

537540
if (!this._isPreviewMode) {
@@ -553,16 +556,16 @@ export class ProductTourManager {
553556
if (this._activeTour) {
554557
const currentStep = this._activeTour.steps[this._currentStepIndex]
555558
if (currentStep) {
556-
this._captureEvent('product tour button clicked', {
557-
$product_tour_id: this._activeTour.id,
558-
$product_tour_name: this._activeTour.name,
559-
$product_tour_iteration: this._activeTour.current_iteration || 1,
560-
$product_tour_step_id: currentStep.id,
561-
$product_tour_step_order: this._currentStepIndex,
562-
$product_tour_button_text: button.text,
563-
$product_tour_button_action: button.action,
564-
...(button.link && { $product_tour_button_link: button.link }),
565-
...(button.tourId && { $product_tour_button_tour_id: button.tourId }),
559+
this._captureEvent(ProductTourEventName.BUTTON_CLICKED, {
560+
[ProductTourEventProperties.TOUR_ID]: this._activeTour.id,
561+
[ProductTourEventProperties.TOUR_NAME]: this._activeTour.name,
562+
[ProductTourEventProperties.TOUR_ITERATION]: this._activeTour.current_iteration || 1,
563+
[ProductTourEventProperties.TOUR_STEP_ID]: currentStep.id,
564+
[ProductTourEventProperties.TOUR_STEP_ORDER]: this._currentStepIndex,
565+
[ProductTourEventProperties.TOUR_BUTTON_TEXT]: button.text,
566+
[ProductTourEventProperties.TOUR_BUTTON_ACTION]: button.action,
567+
...(button.link && { [ProductTourEventProperties.TOUR_BUTTON_LINK]: button.link }),
568+
...(button.tourId && { [ProductTourEventProperties.TOUR_BUTTON_TOUR_ID]: button.tourId }),
566569
})
567570
}
568571
}
@@ -594,9 +597,9 @@ export class ProductTourManager {
594597
return
595598
}
596599

597-
this._captureEvent('product tour completed', {
598-
$product_tour_id: this._activeTour.id,
599-
$product_tour_steps_count: this._activeTour.steps.length,
600+
this._captureEvent(ProductTourEventName.COMPLETED, {
601+
[ProductTourEventProperties.TOUR_ID]: this._activeTour.id,
602+
[ProductTourEventProperties.TOUR_STEPS_COUNT]: this._activeTour.steps.length,
600603
})
601604

602605
if (!this._isPreviewMode) {
@@ -628,12 +631,7 @@ export class ProductTourManager {
628631

629632
// Banner step - render full-width banner
630633
if (step.type === 'banner') {
631-
this._captureEvent('product tour step shown', {
632-
$product_tour_id: this._activeTour.id,
633-
$product_tour_step_id: step.id,
634-
$product_tour_step_order: this._currentStepIndex,
635-
$product_tour_step_type: 'banner',
636-
})
634+
this._captureStepShown()
637635

638636
this._isResuming = false
639637
this._renderBanner()
@@ -653,12 +651,7 @@ export class ProductTourManager {
653651

654652
// Screen-positioned step (no element targeting) - render without a target element
655653
if (!hasElementTarget(step)) {
656-
this._captureEvent('product tour step shown', {
657-
$product_tour_id: this._activeTour.id,
658-
$product_tour_step_id: step.id,
659-
$product_tour_step_order: this._currentStepIndex,
660-
$product_tour_step_type: step.type,
661-
})
654+
this._captureStepShown()
662655

663656
this._isResuming = false
664657
this._renderTooltipWithPreact(null)
@@ -668,8 +661,8 @@ export class ProductTourManager {
668661
const result = findStepElement(step)
669662

670663
const inferenceProps = {
671-
$use_manual_selector: step.useManualSelector ?? false,
672-
$inference_data_present: !!step.inferenceData,
664+
[ProductTourEventProperties.USE_MANUAL_SELECTOR]: step.useManualSelector ?? false,
665+
[ProductTourEventProperties.INFERENCE_DATA_PRESENT]: !!step.inferenceData,
673666
}
674667

675668
const previousStep = this._currentStepIndex > 0 ? this._activeTour.steps[this._currentStepIndex - 1] : null
@@ -692,16 +685,9 @@ export class ProductTourManager {
692685

693686
const waitDurationMs = retryCount * retryTimeout
694687

695-
this._captureEvent('product tour step selector failed', {
696-
$product_tour_id: this._activeTour.id,
697-
$product_tour_step_id: step.id,
698-
$product_tour_step_order: this._currentStepIndex,
699-
$product_tour_step_selector: step.selector,
700-
$product_tour_error: result.error,
701-
$product_tour_matches_count: result.matchCount,
702-
$product_tour_failure_phase: 'runtime',
703-
$product_tour_waited_for_element: shouldWaitForElement,
704-
$product_tour_wait_duration_ms: waitDurationMs,
688+
this._captureStepSelectorFailed(result, {
689+
[ProductTourEventProperties.TOUR_WAITED_FOR_ELEMENT]: shouldWaitForElement,
690+
[ProductTourEventProperties.TOUR_WAIT_DURATION_MS]: waitDurationMs,
705691
...inferenceProps,
706692
})
707693

@@ -721,16 +707,7 @@ export class ProductTourManager {
721707
}
722708

723709
if (result.error === 'multiple_matches') {
724-
this._captureEvent('product tour step selector failed', {
725-
$product_tour_id: this._activeTour.id,
726-
$product_tour_step_id: step.id,
727-
$product_tour_step_order: this._currentStepIndex,
728-
$product_tour_step_selector: step.selector,
729-
$product_tour_error: result.error,
730-
$product_tour_matches_count: result.matchCount,
731-
$product_tour_failure_phase: 'runtime',
732-
...inferenceProps,
733-
})
710+
this._captureStepSelectorFailed(result, inferenceProps)
734711
// Continue with first match for multiple_matches case
735712
}
736713

@@ -741,16 +718,13 @@ export class ProductTourManager {
741718
const element = result.element
742719
const metadata = getElementMetadata(element)
743720

744-
this._captureEvent('product tour step shown', {
745-
$product_tour_id: this._activeTour.id,
746-
$product_tour_step_id: step.id,
747-
$product_tour_step_order: this._currentStepIndex,
748-
$product_tour_step_selector: step.selector,
749-
$product_tour_step_selector_found: true,
750-
$product_tour_step_element_tag: metadata.tag,
751-
$product_tour_step_element_id: metadata.id,
752-
$product_tour_step_element_classes: metadata.classes,
753-
$product_tour_step_element_text: metadata.text,
721+
this._captureStepShown({
722+
[ProductTourEventProperties.TOUR_STEP_SELECTOR]: step.selector,
723+
[ProductTourEventProperties.TOUR_STEP_SELECTOR_FOUND]: true,
724+
[ProductTourEventProperties.TOUR_STEP_ELEMENT_TAG]: metadata.tag,
725+
[ProductTourEventProperties.TOUR_STEP_ELEMENT_ID]: metadata.id,
726+
[ProductTourEventProperties.TOUR_STEP_ELEMENT_CLASSES]: metadata.classes,
727+
[ProductTourEventProperties.TOUR_STEP_ELEMENT_TEXT]: metadata.text,
754728
...inferenceProps,
755729
})
756730

@@ -797,9 +771,9 @@ export class ProductTourManager {
797771
const result = retrieveBannerShadow(this._activeTour, step.bannerConfig)
798772

799773
if (!result) {
800-
this._captureEvent('product tour banner container selector failed', {
801-
$product_tour_id: this._activeTour.id,
802-
$product_tour_banner_selector: step?.bannerConfig?.selector,
774+
this._captureEvent(ProductTourEventName.BANNER_CONTAINER_SELECTOR_FAILED, {
775+
[ProductTourEventProperties.TOUR_ID]: this._activeTour.id,
776+
[ProductTourEventProperties.TOUR_BANNER_SELECTOR]: step?.bannerConfig?.selector,
803777
})
804778
this.dismissTour('container_unavailable')
805779
return
@@ -837,12 +811,8 @@ export class ProductTourManager {
837811
const questionId = step.linkedSurveyQuestionId
838812
const questionText = step.survey?.questionText || ''
839813

840-
this._captureEvent('product tour step shown', {
841-
$product_tour_id: this._activeTour.id,
842-
$product_tour_step_id: step.id,
843-
$product_tour_step_order: this._currentStepIndex,
844-
$product_tour_step_type: 'survey',
845-
$product_tour_linked_survey_id: surveyId,
814+
this._captureStepShown({
815+
[ProductTourEventProperties.TOUR_LINKED_SURVEY_ID]: surveyId,
846816
})
847817

848818
this._captureEvent(SurveyEventName.SHOWN, {
@@ -998,13 +968,44 @@ export class ProductTourManager {
998968
})
999969
}
1000970

1001-
private _captureEvent(eventName: string, properties: Record<string, any>): void {
971+
private _captureEvent(eventName: ProductTourEventName | SurveyEventName, properties: Record<string, any>): void {
1002972
if (this._isPreviewMode) {
1003973
return
1004974
}
1005975
this._instance.capture(eventName, properties)
1006976
}
1007977

978+
private _captureStepShown(extraProps?: Record<string, any>): void {
979+
if (!this._activeTour) {
980+
return
981+
}
982+
const step = this._activeTour.steps[this._currentStepIndex]
983+
this._captureEvent(ProductTourEventName.STEP_SHOWN, {
984+
[ProductTourEventProperties.TOUR_ID]: this._activeTour.id,
985+
[ProductTourEventProperties.TOUR_STEP_ID]: step.id,
986+
[ProductTourEventProperties.TOUR_STEP_ORDER]: this._currentStepIndex,
987+
[ProductTourEventProperties.TOUR_STEP_TYPE]: step.type,
988+
...extraProps,
989+
})
990+
}
991+
992+
private _captureStepSelectorFailed(result: ElementFindResult, extraProps?: Record<string, any>): void {
993+
if (!this._activeTour) {
994+
return
995+
}
996+
const step = this._activeTour.steps[this._currentStepIndex]
997+
this._captureEvent(ProductTourEventName.STEP_SELECTOR_FAILED, {
998+
[ProductTourEventProperties.TOUR_ID]: this._activeTour.id,
999+
[ProductTourEventProperties.TOUR_STEP_ID]: step.id,
1000+
[ProductTourEventProperties.TOUR_STEP_ORDER]: this._currentStepIndex,
1001+
[ProductTourEventProperties.TOUR_STEP_SELECTOR]: step.selector,
1002+
[ProductTourEventProperties.TOUR_ERROR]: result.error,
1003+
[ProductTourEventProperties.TOUR_MATCHES_COUNT]: result.matchCount,
1004+
[ProductTourEventProperties.TOUR_FAILURE_PHASE]: 'runtime',
1005+
...extraProps,
1006+
})
1007+
}
1008+
10081009
// Public API methods delegated from PostHogProductTours
10091010
getActiveProductTours(callback: ProductTourCallback): void {
10101011
this._instance.productTours?.getProductTours((tours, context) => {

packages/browser/src/posthog-product-tours-types.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,3 +167,45 @@ export interface ShowTourOptions {
167167
reason?: ProductTourRenderReason
168168
enableStrictValidation?: boolean
169169
}
170+
171+
export enum ProductTourEventName {
172+
SHOWN = 'product tour shown',
173+
DISMISSED = 'product tour dismissed',
174+
COMPLETED = 'product tour completed',
175+
STEP_SHOWN = 'product tour step shown',
176+
STEP_COMPLETED = 'product tour step completed',
177+
BUTTON_CLICKED = 'product tour button clicked',
178+
STEP_SELECTOR_FAILED = 'product tour step selector failed',
179+
BANNER_CONTAINER_SELECTOR_FAILED = 'product tour banner container selector failed',
180+
}
181+
182+
export enum ProductTourEventProperties {
183+
TOUR_ID = '$product_tour_id',
184+
TOUR_NAME = '$product_tour_name',
185+
TOUR_ITERATION = '$product_tour_iteration',
186+
TOUR_RENDER_REASON = '$product_tour_render_reason',
187+
TOUR_STEP_ID = '$product_tour_step_id',
188+
TOUR_STEP_ORDER = '$product_tour_step_order',
189+
TOUR_STEP_TYPE = '$product_tour_step_type',
190+
TOUR_DISMISS_REASON = '$product_tour_dismiss_reason',
191+
TOUR_BUTTON_TEXT = '$product_tour_button_text',
192+
TOUR_BUTTON_ACTION = '$product_tour_button_action',
193+
TOUR_BUTTON_LINK = '$product_tour_button_link',
194+
TOUR_BUTTON_TOUR_ID = '$product_tour_button_tour_id',
195+
TOUR_STEPS_COUNT = '$product_tour_steps_count',
196+
TOUR_STEP_SELECTOR = '$product_tour_step_selector',
197+
TOUR_STEP_SELECTOR_FOUND = '$product_tour_step_selector_found',
198+
TOUR_STEP_ELEMENT_TAG = '$product_tour_step_element_tag',
199+
TOUR_STEP_ELEMENT_ID = '$product_tour_step_element_id',
200+
TOUR_STEP_ELEMENT_CLASSES = '$product_tour_step_element_classes',
201+
TOUR_STEP_ELEMENT_TEXT = '$product_tour_step_element_text',
202+
TOUR_ERROR = '$product_tour_error',
203+
TOUR_MATCHES_COUNT = '$product_tour_matches_count',
204+
TOUR_FAILURE_PHASE = '$product_tour_failure_phase',
205+
TOUR_WAITED_FOR_ELEMENT = '$product_tour_waited_for_element',
206+
TOUR_WAIT_DURATION_MS = '$product_tour_wait_duration_ms',
207+
TOUR_BANNER_SELECTOR = '$product_tour_banner_selector',
208+
TOUR_LINKED_SURVEY_ID = '$product_tour_linked_survey_id',
209+
USE_MANUAL_SELECTOR = '$use_manual_selector',
210+
INFERENCE_DATA_PRESENT = '$inference_data_present',
211+
}

packages/browser/src/utils/product-tour-event-receiver.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { PRODUCT_TOURS_ACTIVATED } from '../constants'
2-
import { ProductTour } from '../posthog-product-tours-types'
2+
import { ProductTour, ProductTourEventName } from '../posthog-product-tours-types'
33
import { PostHog } from '../posthog-core'
44
import { EventReceiver } from './event-receiver'
55
import { createLogger } from './logger'
@@ -18,7 +18,7 @@ export class ProductTourEventReceiver extends EventReceiver<ProductTour> {
1818
}
1919

2020
protected _getShownEventName(): string {
21-
return 'product tour shown'
21+
return ProductTourEventName.SHOWN
2222
}
2323

2424
protected _getItems(callback: (items: ProductTour[]) => void): void {

packages/browser/terser-mangled-names.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@
4848
"_capturePageview",
4949
"_captureSnapshot",
5050
"_captureSnapshotBuffered",
51+
"_captureStepSelectorFailed",
52+
"_captureStepShown",
5153
"_checkAction",
5254
"_checkClickTimer",
5355
"_checkClicks",

0 commit comments

Comments
 (0)