diff --git a/.changeset/two-monkeys-swim.md b/.changeset/two-monkeys-swim.md new file mode 100644 index 0000000000..c67464f343 --- /dev/null +++ b/.changeset/two-monkeys-swim.md @@ -0,0 +1,5 @@ +--- +'posthog-js': patch +--- + +add banner click tracking for tours diff --git a/packages/browser/src/extensions/product-tours/components/ProductTourBanner.tsx b/packages/browser/src/extensions/product-tours/components/ProductTourBanner.tsx index 1950ad2417..50c7a3f14a 100644 --- a/packages/browser/src/extensions/product-tours/components/ProductTourBanner.tsx +++ b/packages/browser/src/extensions/product-tours/components/ProductTourBanner.tsx @@ -6,7 +6,7 @@ import { cancelSVG } from '../../surveys/icons' export interface ProductTourBannerProps { step: ProductTourStep onDismiss: () => void - onTriggerTour?: () => void + onActionClick?: () => void displayFrequency?: ProductTourDisplayFrequency } @@ -17,15 +17,16 @@ interface BannerWrapperProps { interface LinkWrapperProps extends BannerWrapperProps { href: string + onClick?: () => void } interface ButtonWrapperProps extends BannerWrapperProps { onClick: () => void } -function LinkWrapper({ class: className, href, children }: LinkWrapperProps): h.JSX.Element { +function LinkWrapper({ class: className, href, onClick, children }: LinkWrapperProps): h.JSX.Element { return ( - + {children} ) @@ -58,7 +59,7 @@ function StaticWrapper({ class: className, children }: BannerWrapperProps): h.JS export function ProductTourBanner({ step, onDismiss, - onTriggerTour, + onActionClick, displayFrequency, }: ProductTourBannerProps): h.JSX.Element { const config = step.bannerConfig ?? { behavior: 'sticky' } @@ -97,15 +98,15 @@ export function ProductTourBanner({ if (action?.type === 'link' && action.link) { return ( - + {content} ) } - if (action?.type === 'trigger_tour' && onTriggerTour) { + if (action?.type === 'trigger_tour' && onActionClick) { return ( - + {content} ) diff --git a/packages/browser/src/extensions/product-tours/product-tour.css b/packages/browser/src/extensions/product-tours/product-tour.css index b811b1337c..97048e1859 100644 --- a/packages/browser/src/extensions/product-tours/product-tour.css +++ b/packages/browser/src/extensions/product-tours/product-tour.css @@ -335,6 +335,7 @@ } .ph-tour-button { + text-decoration: none; display: inline-flex; align-items: center; justify-content: center; diff --git a/packages/browser/src/extensions/product-tours/product-tours.tsx b/packages/browser/src/extensions/product-tours/product-tours.tsx index 1e7a95e0fa..d8205976d9 100644 --- a/packages/browser/src/extensions/product-tours/product-tours.tsx +++ b/packages/browser/src/extensions/product-tours/product-tours.tsx @@ -584,6 +584,35 @@ export class ProductTourManager { this._cleanup() } + private _handleBannerActionClick = (): void => { + if (!this._activeTour) { + return + } + + const step = this._getCurrentStep() + if (!step) { + return + } + + const action = step.bannerConfig?.action + + this._captureEvent(ProductTourEventName.BANNER_ACTION_CLICKED, { + [ProductTourEventProperties.TOUR_ID]: this._activeTour.id, + [ProductTourEventProperties.TOUR_NAME]: this._activeTour.name, + [ProductTourEventProperties.TOUR_ITERATION]: this._activeTour.current_iteration || 1, + [ProductTourEventProperties.TOUR_STEP_ID]: step.id, + [ProductTourEventProperties.TOUR_STEP_ORDER]: this._currentStepIndex, + [ProductTourEventProperties.TOUR_BUTTON_ACTION]: action?.type, + [ProductTourEventProperties.TOUR_BUTTON_LINK]: action?.link, + [ProductTourEventProperties.TOUR_BUTTON_TOUR_ID]: action?.tourId, + }) + + if (action?.type === 'trigger_tour' && action.tourId) { + this._cleanup() + this.showTourById(action.tourId) + } + } + private _handleButtonClick = (button: ProductTourStepButton): void => { if (this._activeTour) { const currentStep = this._activeTour.steps[this._currentStepIndex] @@ -821,19 +850,11 @@ export class ProductTourManager { const { shadow } = result - const handleTriggerTour = () => { - const tourId = step.bannerConfig?.action?.tourId - if (tourId) { - this._cleanup() - this.showTourById(tourId) - } - } - render( this.dismissTour('user_clicked_skip')} - onTriggerTour={handleTriggerTour} + onActionClick={this._handleBannerActionClick} displayFrequency={this._activeTour.display_frequency} />, shadow diff --git a/packages/browser/src/posthog-product-tours-types.ts b/packages/browser/src/posthog-product-tours-types.ts index 89193c33e8..4973b65808 100644 --- a/packages/browser/src/posthog-product-tours-types.ts +++ b/packages/browser/src/posthog-product-tours-types.ts @@ -197,6 +197,7 @@ export enum ProductTourEventName { BUTTON_CLICKED = 'product tour button clicked', STEP_SELECTOR_FAILED = 'product tour step selector failed', BANNER_CONTAINER_SELECTOR_FAILED = 'product tour banner container selector failed', + BANNER_ACTION_CLICKED = 'product tour banner action clicked', } export enum ProductTourEventProperties { diff --git a/packages/browser/terser-mangled-names.json b/packages/browser/terser-mangled-names.json index d596728af7..4604ff42ff 100644 --- a/packages/browser/terser-mangled-names.json +++ b/packages/browser/terser-mangled-names.json @@ -183,6 +183,7 @@ "_getValidEvaluationEnvironments", "_getWindowId", "_handleBackToTickets", + "_handleBannerActionClick", "_handleButtonClick", "_handleClose", "_handleFormEmailChange",