Skip to content

Commit 2bc380a

Browse files
committed
Add useAnalytics hook
1 parent b5176ec commit 2bc380a

File tree

3 files changed

+110
-3
lines changed

3 files changed

+110
-3
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
'use client';
2+
3+
import { useAnalytics } from '@dub/analytics/react';
4+
5+
export function DiscountBanner() {
6+
const { partner } = useAnalytics();
7+
8+
console.log({ partner });
9+
10+
return null;
11+
}

packages/script/src/base.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,12 +119,40 @@
119119

120120
cookieManager.set(DUB_PARTNER_COOKIE, JSON.stringify(encodedData));
121121
}
122+
123+
window.dispatchEvent(new CustomEvent('DubAnalytics:tracked'));
122124
}
123125
});
124126
}
125127

128+
function getPartnerData() {
129+
const partnerData = cookieManager.get(DUB_PARTNER_COOKIE);
130+
131+
if (!partnerData) {
132+
return null;
133+
}
134+
135+
try {
136+
const parsed = JSON.parse(partnerData);
137+
138+
if (parsed.partner) {
139+
parsed.partner.name = decodeURIComponent(parsed.partner.name);
140+
parsed.partner.image = decodeURIComponent(parsed.partner.image);
141+
}
142+
143+
return parsed;
144+
} catch (e) {
145+
return null;
146+
}
147+
}
148+
126149
// Initialize tracking
127150
function init() {
151+
if (!window._dubAnalytics.initialized) {
152+
window.dispatchEvent(new CustomEvent('DubAnalytics:ready'));
153+
window._dubAnalytics.initialized = true;
154+
}
155+
128156
const params = new URLSearchParams(location.search);
129157

130158
const shouldSetCookie = () => {
@@ -159,6 +187,8 @@
159187
p: QUERY_PARAM, // was QUERY_PARAM
160188
v: QUERY_PARAM_VALUE, // was QUERY_PARAM_VALUE
161189
n: DOMAINS_CONFIG, // was DOMAINS_CONFIG
190+
getPartnerData,
191+
initialized: false,
162192
};
163193

164194
// Initialize

packages/web/src/react.tsx

Lines changed: 69 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,22 @@
1-
import { useEffect } from 'react';
1+
import { useEffect, useState } from 'react';
22
import { inject } from './generic';
33
import type { AnalyticsProps } from './types';
44

5+
interface PartnerData {
6+
clickId: string;
7+
partner: {
8+
id: string;
9+
name: string;
10+
image: string;
11+
} | null;
12+
discount: {
13+
id: string;
14+
amount: number;
15+
type: string;
16+
maxDuration: number;
17+
} | null;
18+
}
19+
520
/**
621
* Injects the Dub Web Analytics script into the page head.
722
* @param props - Analytics options.
@@ -26,5 +41,56 @@ function Analytics(props: AnalyticsProps): null {
2641
return null;
2742
}
2843

29-
export { Analytics };
30-
export type { AnalyticsProps };
44+
/**
45+
* Hook to access partner data from Dub Analytics.
46+
* @returns Object containing partner data if available.
47+
* ```js
48+
* import { useAnalytics } from '@dub/analytics/react';
49+
*
50+
* function MyComponent() {
51+
* const { partner } = useAnalytics();
52+
*
53+
* if (partner) {
54+
* return (
55+
* <div>
56+
* <img src={partner.partner.image} alt={partner.partner.name} />
57+
* <h2>{partner.partner.name}</h2>
58+
* {partner.discount && (
59+
* <p>Discount: {partner.discount.amount}%</p>
60+
* )}
61+
* </div>
62+
* );
63+
* }
64+
*
65+
* return null;
66+
* }
67+
* ```
68+
*/
69+
function useAnalytics() {
70+
const [partner, setPartner] = useState<PartnerData | null>(null);
71+
72+
useEffect(() => {
73+
const handleEvent = () => {
74+
const dubAnalytics = (window as any)._dubAnalytics;
75+
76+
if (dubAnalytics) {
77+
setPartner(dubAnalytics.getPartnerData());
78+
}
79+
};
80+
81+
window.addEventListener('DubAnalytics:tracked', handleEvent);
82+
83+
handleEvent();
84+
85+
return () => {
86+
window.removeEventListener('DubAnalytics:tracked', handleEvent);
87+
};
88+
}, []);
89+
90+
return {
91+
partner,
92+
};
93+
}
94+
95+
export { Analytics, useAnalytics };
96+
export type { AnalyticsProps, PartnerData };

0 commit comments

Comments
 (0)