Skip to content

Commit 36713c1

Browse files
committed
feat(product tours): add click tracking to banner actions
1 parent d36a6ed commit 36713c1

File tree

5 files changed

+32
-12
lines changed

5 files changed

+32
-12
lines changed

.changeset/two-monkeys-swim.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+
add banner click tracking for tours

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

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { cancelSVG } from '../../surveys/icons'
66
export interface ProductTourBannerProps {
77
step: ProductTourStep
88
onDismiss: () => void
9-
onTriggerTour?: () => void
9+
onActionClick?: () => void
1010
displayFrequency?: ProductTourDisplayFrequency
1111
}
1212

@@ -17,15 +17,16 @@ interface BannerWrapperProps {
1717

1818
interface LinkWrapperProps extends BannerWrapperProps {
1919
href: string
20+
onClick?: () => void
2021
}
2122

2223
interface ButtonWrapperProps extends BannerWrapperProps {
2324
onClick: () => void
2425
}
2526

26-
function LinkWrapper({ class: className, href, children }: LinkWrapperProps): h.JSX.Element {
27+
function LinkWrapper({ class: className, href, onClick, children }: LinkWrapperProps): h.JSX.Element {
2728
return (
28-
<a class={className} href={href} target="_blank" rel="noopener noreferrer">
29+
<a class={className} href={href} target="_blank" rel="noopener noreferrer" onClick={onClick}>
2930
{children}
3031
</a>
3132
)
@@ -58,7 +59,7 @@ function StaticWrapper({ class: className, children }: BannerWrapperProps): h.JS
5859
export function ProductTourBanner({
5960
step,
6061
onDismiss,
61-
onTriggerTour,
62+
onActionClick,
6263
displayFrequency,
6364
}: ProductTourBannerProps): h.JSX.Element {
6465
const config = step.bannerConfig ?? { behavior: 'sticky' }
@@ -97,15 +98,15 @@ export function ProductTourBanner({
9798

9899
if (action?.type === 'link' && action.link) {
99100
return (
100-
<LinkWrapper class={classNames} href={action.link}>
101+
<LinkWrapper class={classNames} href={action.link} onClick={onActionClick}>
101102
{content}
102103
</LinkWrapper>
103104
)
104105
}
105106

106-
if (action?.type === 'trigger_tour' && onTriggerTour) {
107+
if (action?.type === 'trigger_tour' && onActionClick) {
107108
return (
108-
<ButtonWrapper class={classNames} onClick={onTriggerTour}>
109+
<ButtonWrapper class={classNames} onClick={onActionClick}>
109110
{content}
110111
</ButtonWrapper>
111112
)

packages/browser/src/extensions/product-tours/product-tour.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,7 @@
335335
}
336336

337337
.ph-tour-button {
338+
text-decoration: none;
338339
display: inline-flex;
339340
align-items: center;
340341
justify-content: center;

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

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -798,19 +798,31 @@ export class ProductTourManager {
798798

799799
const { shadow } = result
800800

801-
const handleTriggerTour = () => {
802-
const tourId = step.bannerConfig?.action?.tourId
803-
if (tourId) {
801+
const action = step.bannerConfig?.action
802+
803+
const handleActionClick = () => {
804+
this._captureEvent(ProductTourEventName.BANNER_ACTION_CLICKED, {
805+
[ProductTourEventProperties.TOUR_ID]: this._activeTour!.id,
806+
[ProductTourEventProperties.TOUR_NAME]: this._activeTour!.name,
807+
[ProductTourEventProperties.TOUR_ITERATION]: this._activeTour!.current_iteration || 1,
808+
[ProductTourEventProperties.TOUR_STEP_ID]: step.id,
809+
[ProductTourEventProperties.TOUR_STEP_ORDER]: this._currentStepIndex,
810+
[ProductTourEventProperties.TOUR_BUTTON_ACTION]: action?.type,
811+
...(action?.link && { [ProductTourEventProperties.TOUR_BUTTON_LINK]: action.link }),
812+
...(action?.tourId && { [ProductTourEventProperties.TOUR_BUTTON_TOUR_ID]: action.tourId }),
813+
})
814+
815+
if (action?.type === 'trigger_tour' && action.tourId) {
804816
this._cleanup()
805-
this.showTourById(tourId)
817+
this.showTourById(action.tourId)
806818
}
807819
}
808820

809821
render(
810822
<ProductTourBanner
811823
step={step}
812824
onDismiss={() => this.dismissTour('user_clicked_skip')}
813-
onTriggerTour={handleTriggerTour}
825+
onActionClick={handleActionClick}
814826
displayFrequency={this._activeTour.display_frequency}
815827
/>,
816828
shadow

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ export enum ProductTourEventName {
179179
BUTTON_CLICKED = 'product tour button clicked',
180180
STEP_SELECTOR_FAILED = 'product tour step selector failed',
181181
BANNER_CONTAINER_SELECTOR_FAILED = 'product tour banner container selector failed',
182+
BANNER_ACTION_CLICKED = 'product tour banner action clicked',
182183
}
183184

184185
export enum ProductTourEventProperties {

0 commit comments

Comments
 (0)