@affiliateo/web 1.5.0 → 1.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/provider.js +41 -57
- package/package.json +1 -1
package/dist/provider.js
CHANGED
|
@@ -14,7 +14,8 @@ function setCookie(name, value, days) {
|
|
|
14
14
|
return;
|
|
15
15
|
const dt = new Date();
|
|
16
16
|
dt.setTime(dt.getTime() + days * 864e5);
|
|
17
|
-
|
|
17
|
+
const secure = window.location.protocol === 'https:' ? ';Secure' : '';
|
|
18
|
+
document.cookie = `${name}=${value};expires=${dt.toUTCString()};path=/;SameSite=Lax${secure}`;
|
|
18
19
|
}
|
|
19
20
|
// Generate UUID
|
|
20
21
|
function uuid() {
|
|
@@ -43,8 +44,6 @@ export function AffiliateoProvider({ campaignId, apiUrl, children, }) {
|
|
|
43
44
|
});
|
|
44
45
|
const apiBase = (apiUrl || DEFAULT_API_URL).replace(/\/$/, '');
|
|
45
46
|
const campaignIdRef = useRef(campaignId);
|
|
46
|
-
const visitorIdRef = useRef(null);
|
|
47
|
-
const refRef = useRef(null);
|
|
48
47
|
const sentRef = useRef(false);
|
|
49
48
|
useEffect(() => {
|
|
50
49
|
if (typeof window === 'undefined')
|
|
@@ -54,28 +53,32 @@ export function AffiliateoProvider({ campaignId, apiUrl, children, }) {
|
|
|
54
53
|
if (!vid) {
|
|
55
54
|
vid = uuid();
|
|
56
55
|
}
|
|
57
|
-
setCookie('affiliateo_visitor_id', vid,
|
|
58
|
-
setCookie('affiliateo_campaign_id', campaignIdRef.current,
|
|
59
|
-
visitorIdRef.current = vid;
|
|
56
|
+
setCookie('affiliateo_visitor_id', vid, 90);
|
|
57
|
+
setCookie('affiliateo_campaign_id', campaignIdRef.current, 90);
|
|
60
58
|
// Read ref from URL params
|
|
61
59
|
const params = new URLSearchParams(window.location.search);
|
|
62
60
|
const ref = params.get('ref') || params.get('via') || params.get('source') || getCookie('affiliateo_ref') || null;
|
|
63
61
|
if (ref) {
|
|
64
|
-
setCookie('affiliateo_ref', ref,
|
|
62
|
+
setCookie('affiliateo_ref', ref, 90);
|
|
65
63
|
}
|
|
66
|
-
refRef.current = ref;
|
|
67
64
|
setState({ refCode: ref, visitorId: vid });
|
|
68
|
-
//
|
|
69
|
-
|
|
65
|
+
// Throttle: max 1 pageview per second
|
|
66
|
+
let lastSendTime = 0;
|
|
67
|
+
// Send pageview
|
|
68
|
+
function sendPageview() {
|
|
69
|
+
const now = Date.now();
|
|
70
|
+
if (now - lastSendTime < 1000)
|
|
71
|
+
return;
|
|
72
|
+
lastSendTime = now;
|
|
70
73
|
const payload = {
|
|
71
|
-
type,
|
|
74
|
+
type: 'pageview',
|
|
72
75
|
campaign_id: campaignIdRef.current,
|
|
73
|
-
visitor_id:
|
|
76
|
+
visitor_id: vid,
|
|
74
77
|
url: window.location.href,
|
|
75
78
|
path: window.location.pathname,
|
|
76
79
|
hostname: window.location.hostname,
|
|
77
80
|
referrer: document.referrer || '',
|
|
78
|
-
ref:
|
|
81
|
+
ref: ref || getCookie('affiliateo_ref') || '',
|
|
79
82
|
utm_source: params.get('utm_source') || '',
|
|
80
83
|
utm_medium: params.get('utm_medium') || '',
|
|
81
84
|
utm_campaign: params.get('utm_campaign') || '',
|
|
@@ -94,55 +97,36 @@ export function AffiliateoProvider({ campaignId, apiUrl, children, }) {
|
|
|
94
97
|
}).catch(() => { });
|
|
95
98
|
}
|
|
96
99
|
}
|
|
97
|
-
//
|
|
98
|
-
|
|
99
|
-
const hasActiveSession = !!getCookie(SESSION_COOKIE);
|
|
100
|
-
if (!hasActiveSession && !sentRef.current) {
|
|
100
|
+
// Send pageview on mount (first load or page navigation)
|
|
101
|
+
if (!sentRef.current) {
|
|
101
102
|
sentRef.current = true;
|
|
102
|
-
|
|
103
|
-
}
|
|
104
|
-
// Refresh session cookie (30 min sliding window)
|
|
105
|
-
setCookie(SESSION_COOKIE, '1', 1 / 48); // 30 minutes = 1/48 of a day
|
|
106
|
-
// session_end only fires when actually leaving the site (tab close, navigate away)
|
|
107
|
-
// NOT on SPA page navigations or tab switching
|
|
108
|
-
let ended = false;
|
|
109
|
-
function onLeave() {
|
|
110
|
-
if (ended)
|
|
111
|
-
return;
|
|
112
|
-
ended = true;
|
|
113
|
-
send('session_end');
|
|
103
|
+
sendPageview();
|
|
114
104
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
hiddenTimer = setTimeout(() => {
|
|
122
|
-
send('session_end');
|
|
123
|
-
ended = true;
|
|
124
|
-
}, 30 * 60 * 1000);
|
|
125
|
-
}
|
|
126
|
-
else if (document.visibilityState === 'visible') {
|
|
127
|
-
// User came back — cancel the timer, refresh session cookie
|
|
128
|
-
if (hiddenTimer) {
|
|
129
|
-
clearTimeout(hiddenTimer);
|
|
130
|
-
hiddenTimer = null;
|
|
131
|
-
}
|
|
132
|
-
// If session expired while away (30+ min), start a new one
|
|
133
|
-
if (!getCookie(SESSION_COOKIE)) {
|
|
134
|
-
ended = false;
|
|
135
|
-
send('session_start');
|
|
136
|
-
}
|
|
137
|
-
setCookie(SESSION_COOKIE, '1', 1 / 48);
|
|
105
|
+
// For SPA: listen for URL changes (popstate + pushState/replaceState)
|
|
106
|
+
let lastPath = window.location.pathname;
|
|
107
|
+
function onUrlChange() {
|
|
108
|
+
if (window.location.pathname !== lastPath) {
|
|
109
|
+
lastPath = window.location.pathname;
|
|
110
|
+
sendPageview();
|
|
138
111
|
}
|
|
139
112
|
}
|
|
140
|
-
|
|
113
|
+
// Listen for browser back/forward
|
|
114
|
+
window.addEventListener('popstate', onUrlChange);
|
|
115
|
+
// Patch pushState/replaceState to detect SPA navigations
|
|
116
|
+
const origPushState = history.pushState;
|
|
117
|
+
const origReplaceState = history.replaceState;
|
|
118
|
+
history.pushState = function (...args) {
|
|
119
|
+
origPushState.apply(this, args);
|
|
120
|
+
onUrlChange();
|
|
121
|
+
};
|
|
122
|
+
history.replaceState = function (...args) {
|
|
123
|
+
origReplaceState.apply(this, args);
|
|
124
|
+
onUrlChange();
|
|
125
|
+
};
|
|
141
126
|
return () => {
|
|
142
|
-
window.removeEventListener('
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
clearTimeout(hiddenTimer);
|
|
127
|
+
window.removeEventListener('popstate', onUrlChange);
|
|
128
|
+
history.pushState = origPushState;
|
|
129
|
+
history.replaceState = origReplaceState;
|
|
146
130
|
};
|
|
147
131
|
}, [campaignId, apiBase]);
|
|
148
132
|
return (_jsx(AffiliateoContext.Provider, { value: state, children: children }));
|