@@ -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'
1214import { SurveyEventName , SurveyEventProperties } from '../../posthog-surveys-types'
1315import {
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 ) => {
0 commit comments