@@ -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 ,
@@ -462,11 +465,11 @@ export class ProductTourManager {
462465 const rendered = this . _renderCurrentStep ( )
463466
464467 if ( rendered ) {
465- this . _captureEvent ( 'product tour shown' , {
466- $product_tour_id : tour . id ,
467- $product_tour_name : tour . name ,
468- $product_tour_iteration : tour . current_iteration || 1 ,
469- $product_tour_render_reason : renderReason ,
468+ this . _captureEvent ( ProductTourEventName . SHOWN , {
469+ [ ProductTourEventProperties . TOUR_ID ] : tour . id ,
470+ [ ProductTourEventProperties . TOUR_NAME ] : tour . name ,
471+ [ ProductTourEventProperties . TOUR_ITERATION ] : tour . current_iteration || 1 ,
472+ [ ProductTourEventProperties . TOUR_RENDER_REASON ] : renderReason ,
470473 } )
471474
472475 if ( ! this . _isPreviewMode ) {
@@ -514,10 +517,10 @@ export class ProductTourManager {
514517
515518 const currentStep = this . _activeTour . steps [ this . _currentStepIndex ]
516519
517- this . _captureEvent ( 'product tour step completed' , {
518- $product_tour_id : this . _activeTour . id ,
519- $product_tour_step_id : currentStep . id ,
520- $product_tour_step_order : this . _currentStepIndex ,
520+ this . _captureEvent ( ProductTourEventName . STEP_COMPLETED , {
521+ [ ProductTourEventProperties . TOUR_ID ] : this . _activeTour . id ,
522+ [ ProductTourEventProperties . TOUR_STEP_ID ] : currentStep . id ,
523+ [ ProductTourEventProperties . TOUR_STEP_ORDER ] : this . _currentStepIndex ,
521524 } )
522525
523526 if ( this . _currentStepIndex < this . _activeTour . steps . length - 1 ) {
@@ -544,11 +547,11 @@ export class ProductTourManager {
544547
545548 const currentStep = this . _activeTour . steps [ this . _currentStepIndex ]
546549
547- this . _captureEvent ( 'product tour dismissed' , {
548- $product_tour_id : this . _activeTour . id ,
549- $product_tour_step_id : currentStep . id ,
550- $product_tour_step_order : this . _currentStepIndex ,
551- $product_tour_dismiss_reason : reason ,
550+ this . _captureEvent ( ProductTourEventName . DISMISSED , {
551+ [ ProductTourEventProperties . TOUR_ID ] : this . _activeTour . id ,
552+ [ ProductTourEventProperties . TOUR_STEP_ID ] : currentStep . id ,
553+ [ ProductTourEventProperties . TOUR_STEP_ORDER ] : this . _currentStepIndex ,
554+ [ ProductTourEventProperties . TOUR_DISMISS_REASON ] : reason ,
552555 } )
553556
554557 if ( ! this . _isPreviewMode ) {
@@ -570,16 +573,16 @@ export class ProductTourManager {
570573 if ( this . _activeTour ) {
571574 const currentStep = this . _activeTour . steps [ this . _currentStepIndex ]
572575 if ( currentStep ) {
573- this . _captureEvent ( 'product tour button clicked' , {
574- $product_tour_id : this . _activeTour . id ,
575- $product_tour_name : this . _activeTour . name ,
576- $product_tour_iteration : this . _activeTour . current_iteration || 1 ,
577- $product_tour_step_id : currentStep . id ,
578- $product_tour_step_order : this . _currentStepIndex ,
579- $product_tour_button_text : button . text ,
580- $product_tour_button_action : button . action ,
581- ...( button . link && { $product_tour_button_link : button . link } ) ,
582- ...( button . tourId && { $product_tour_button_tour_id : button . tourId } ) ,
576+ this . _captureEvent ( ProductTourEventName . BUTTON_CLICKED , {
577+ [ ProductTourEventProperties . TOUR_ID ] : this . _activeTour . id ,
578+ [ ProductTourEventProperties . TOUR_NAME ] : this . _activeTour . name ,
579+ [ ProductTourEventProperties . TOUR_ITERATION ] : this . _activeTour . current_iteration || 1 ,
580+ [ ProductTourEventProperties . TOUR_STEP_ID ] : currentStep . id ,
581+ [ ProductTourEventProperties . TOUR_STEP_ORDER ] : this . _currentStepIndex ,
582+ [ ProductTourEventProperties . TOUR_BUTTON_TEXT ] : button . text ,
583+ [ ProductTourEventProperties . TOUR_BUTTON_ACTION ] : button . action ,
584+ ...( button . link && { [ ProductTourEventProperties . TOUR_BUTTON_LINK ] : button . link } ) ,
585+ ...( button . tourId && { [ ProductTourEventProperties . TOUR_BUTTON_TOUR_ID ] : button . tourId } ) ,
583586 } )
584587 }
585588 }
@@ -611,9 +614,9 @@ export class ProductTourManager {
611614 return
612615 }
613616
614- this . _captureEvent ( 'product tour completed' , {
615- $product_tour_id : this . _activeTour . id ,
616- $product_tour_steps_count : this . _activeTour . steps . length ,
617+ this . _captureEvent ( ProductTourEventName . COMPLETED , {
618+ [ ProductTourEventProperties . TOUR_ID ] : this . _activeTour . id ,
619+ [ ProductTourEventProperties . TOUR_STEPS_COUNT ] : this . _activeTour . steps . length ,
617620 } )
618621
619622 if ( ! this . _isPreviewMode ) {
@@ -645,12 +648,7 @@ export class ProductTourManager {
645648
646649 // Banner step - render full-width banner
647650 if ( step . type === 'banner' ) {
648- this . _captureEvent ( 'product tour step shown' , {
649- $product_tour_id : this . _activeTour . id ,
650- $product_tour_step_id : step . id ,
651- $product_tour_step_order : this . _currentStepIndex ,
652- $product_tour_step_type : 'banner' ,
653- } )
651+ this . _captureStepShown ( )
654652
655653 this . _isResuming = false
656654 this . _renderBanner ( )
@@ -670,12 +668,7 @@ export class ProductTourManager {
670668
671669 // Screen-positioned step (no element targeting) - render without a target element
672670 if ( ! hasElementTarget ( step ) ) {
673- this . _captureEvent ( 'product tour step shown' , {
674- $product_tour_id : this . _activeTour . id ,
675- $product_tour_step_id : step . id ,
676- $product_tour_step_order : this . _currentStepIndex ,
677- $product_tour_step_type : step . type ,
678- } )
671+ this . _captureStepShown ( )
679672
680673 this . _isResuming = false
681674 this . _renderTooltipWithPreact ( null )
@@ -685,8 +678,8 @@ export class ProductTourManager {
685678 const result = findStepElement ( step )
686679
687680 const inferenceProps = {
688- $use_manual_selector : step . useManualSelector ?? false ,
689- $inference_data_present : ! ! step . inferenceData ,
681+ [ ProductTourEventProperties . USE_MANUAL_SELECTOR ] : step . useManualSelector ?? false ,
682+ [ ProductTourEventProperties . INFERENCE_DATA_PRESENT ] : ! ! step . inferenceData ,
690683 }
691684
692685 const previousStep = this . _currentStepIndex > 0 ? this . _activeTour . steps [ this . _currentStepIndex - 1 ] : null
@@ -709,16 +702,9 @@ export class ProductTourManager {
709702
710703 const waitDurationMs = retryCount * retryTimeout
711704
712- this . _captureEvent ( 'product tour step selector failed' , {
713- $product_tour_id : this . _activeTour . id ,
714- $product_tour_step_id : step . id ,
715- $product_tour_step_order : this . _currentStepIndex ,
716- $product_tour_step_selector : step . selector ,
717- $product_tour_error : result . error ,
718- $product_tour_matches_count : result . matchCount ,
719- $product_tour_failure_phase : 'runtime' ,
720- $product_tour_waited_for_element : shouldWaitForElement ,
721- $product_tour_wait_duration_ms : waitDurationMs ,
705+ this . _captureStepSelectorFailed ( result , {
706+ [ ProductTourEventProperties . TOUR_WAITED_FOR_ELEMENT ] : shouldWaitForElement ,
707+ [ ProductTourEventProperties . TOUR_WAIT_DURATION_MS ] : waitDurationMs ,
722708 ...inferenceProps ,
723709 } )
724710
@@ -738,16 +724,7 @@ export class ProductTourManager {
738724 }
739725
740726 if ( result . error === 'multiple_matches' ) {
741- this . _captureEvent ( 'product tour step selector failed' , {
742- $product_tour_id : this . _activeTour . id ,
743- $product_tour_step_id : step . id ,
744- $product_tour_step_order : this . _currentStepIndex ,
745- $product_tour_step_selector : step . selector ,
746- $product_tour_error : result . error ,
747- $product_tour_matches_count : result . matchCount ,
748- $product_tour_failure_phase : 'runtime' ,
749- ...inferenceProps ,
750- } )
727+ this . _captureStepSelectorFailed ( result , inferenceProps )
751728 // Continue with first match for multiple_matches case
752729 }
753730
@@ -758,16 +735,13 @@ export class ProductTourManager {
758735 const element = result . element
759736 const metadata = getElementMetadata ( element )
760737
761- this . _captureEvent ( 'product tour step shown' , {
762- $product_tour_id : this . _activeTour . id ,
763- $product_tour_step_id : step . id ,
764- $product_tour_step_order : this . _currentStepIndex ,
765- $product_tour_step_selector : step . selector ,
766- $product_tour_step_selector_found : true ,
767- $product_tour_step_element_tag : metadata . tag ,
768- $product_tour_step_element_id : metadata . id ,
769- $product_tour_step_element_classes : metadata . classes ,
770- $product_tour_step_element_text : metadata . text ,
738+ this . _captureStepShown ( {
739+ [ ProductTourEventProperties . TOUR_STEP_SELECTOR ] : step . selector ,
740+ [ ProductTourEventProperties . TOUR_STEP_SELECTOR_FOUND ] : true ,
741+ [ ProductTourEventProperties . TOUR_STEP_ELEMENT_TAG ] : metadata . tag ,
742+ [ ProductTourEventProperties . TOUR_STEP_ELEMENT_ID ] : metadata . id ,
743+ [ ProductTourEventProperties . TOUR_STEP_ELEMENT_CLASSES ] : metadata . classes ,
744+ [ ProductTourEventProperties . TOUR_STEP_ELEMENT_TEXT ] : metadata . text ,
771745 ...inferenceProps ,
772746 } )
773747
@@ -814,9 +788,9 @@ export class ProductTourManager {
814788 const result = retrieveBannerShadow ( this . _activeTour , step . bannerConfig )
815789
816790 if ( ! result ) {
817- this . _captureEvent ( 'product tour banner container selector failed' , {
818- $product_tour_id : this . _activeTour . id ,
819- $product_tour_banner_selector : step ?. bannerConfig ?. selector ,
791+ this . _captureEvent ( ProductTourEventName . BANNER_CONTAINER_SELECTOR_FAILED , {
792+ [ ProductTourEventProperties . TOUR_ID ] : this . _activeTour . id ,
793+ [ ProductTourEventProperties . TOUR_BANNER_SELECTOR ] : step ?. bannerConfig ?. selector ,
820794 } )
821795 this . dismissTour ( 'container_unavailable' )
822796 return
@@ -854,12 +828,8 @@ export class ProductTourManager {
854828 const questionId = step . linkedSurveyQuestionId
855829 const questionText = step . survey ?. questionText || ''
856830
857- this . _captureEvent ( 'product tour step shown' , {
858- $product_tour_id : this . _activeTour . id ,
859- $product_tour_step_id : step . id ,
860- $product_tour_step_order : this . _currentStepIndex ,
861- $product_tour_step_type : 'survey' ,
862- $product_tour_linked_survey_id : surveyId ,
831+ this . _captureStepShown ( {
832+ [ ProductTourEventProperties . TOUR_LINKED_SURVEY_ID ] : surveyId ,
863833 } )
864834
865835 this . _captureEvent ( SurveyEventName . SHOWN , {
@@ -1015,13 +985,44 @@ export class ProductTourManager {
1015985 } )
1016986 }
1017987
1018- private _captureEvent ( eventName : string , properties : Record < string , any > ) : void {
988+ private _captureEvent ( eventName : ProductTourEventName | SurveyEventName , properties : Record < string , any > ) : void {
1019989 if ( this . _isPreviewMode ) {
1020990 return
1021991 }
1022992 this . _instance . capture ( eventName , properties )
1023993 }
1024994
995+ private _captureStepShown ( extraProps ?: Record < string , any > ) : void {
996+ if ( ! this . _activeTour ) {
997+ return
998+ }
999+ const step = this . _activeTour . steps [ this . _currentStepIndex ]
1000+ this . _captureEvent ( ProductTourEventName . STEP_SHOWN , {
1001+ [ ProductTourEventProperties . TOUR_ID ] : this . _activeTour . id ,
1002+ [ ProductTourEventProperties . TOUR_STEP_ID ] : step . id ,
1003+ [ ProductTourEventProperties . TOUR_STEP_ORDER ] : this . _currentStepIndex ,
1004+ [ ProductTourEventProperties . TOUR_STEP_TYPE ] : step . type ,
1005+ ...extraProps ,
1006+ } )
1007+ }
1008+
1009+ private _captureStepSelectorFailed ( result : ElementFindResult , extraProps ?: Record < string , any > ) : void {
1010+ if ( ! this . _activeTour ) {
1011+ return
1012+ }
1013+ const step = this . _activeTour . steps [ this . _currentStepIndex ]
1014+ this . _captureEvent ( ProductTourEventName . STEP_SELECTOR_FAILED , {
1015+ [ ProductTourEventProperties . TOUR_ID ] : this . _activeTour . id ,
1016+ [ ProductTourEventProperties . TOUR_STEP_ID ] : step . id ,
1017+ [ ProductTourEventProperties . TOUR_STEP_ORDER ] : this . _currentStepIndex ,
1018+ [ ProductTourEventProperties . TOUR_STEP_SELECTOR ] : step . selector ,
1019+ [ ProductTourEventProperties . TOUR_ERROR ] : result . error ,
1020+ [ ProductTourEventProperties . TOUR_MATCHES_COUNT ] : result . matchCount ,
1021+ [ ProductTourEventProperties . TOUR_FAILURE_PHASE ] : 'runtime' ,
1022+ ...extraProps ,
1023+ } )
1024+ }
1025+
10251026 // Public API methods delegated from PostHogProductTours
10261027 getActiveProductTours ( callback : ProductTourCallback ) : void {
10271028 this . _instance . productTours ?. getProductTours ( ( tours , context ) => {
0 commit comments