@affiliateo/web 1.5.0 → 1.5.1

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.
Files changed (2) hide show
  1. package/dist/provider.js +30 -53
  2. package/package.json +1 -1
package/dist/provider.js CHANGED
@@ -43,8 +43,6 @@ export function AffiliateoProvider({ campaignId, apiUrl, children, }) {
43
43
  });
44
44
  const apiBase = (apiUrl || DEFAULT_API_URL).replace(/\/$/, '');
45
45
  const campaignIdRef = useRef(campaignId);
46
- const visitorIdRef = useRef(null);
47
- const refRef = useRef(null);
48
46
  const sentRef = useRef(false);
49
47
  useEffect(() => {
50
48
  if (typeof window === 'undefined')
@@ -56,26 +54,24 @@ export function AffiliateoProvider({ campaignId, apiUrl, children, }) {
56
54
  }
57
55
  setCookie('affiliateo_visitor_id', vid, 365);
58
56
  setCookie('affiliateo_campaign_id', campaignIdRef.current, 365);
59
- visitorIdRef.current = vid;
60
57
  // Read ref from URL params
61
58
  const params = new URLSearchParams(window.location.search);
62
59
  const ref = params.get('ref') || params.get('via') || params.get('source') || getCookie('affiliateo_ref') || null;
63
60
  if (ref) {
64
61
  setCookie('affiliateo_ref', ref, 365);
65
62
  }
66
- refRef.current = ref;
67
63
  setState({ refCode: ref, visitorId: vid });
68
- // Send event helper
69
- function send(type) {
64
+ // Send pageview
65
+ function sendPageview() {
70
66
  const payload = {
71
- type,
67
+ type: 'pageview',
72
68
  campaign_id: campaignIdRef.current,
73
- visitor_id: visitorIdRef.current,
69
+ visitor_id: vid,
74
70
  url: window.location.href,
75
71
  path: window.location.pathname,
76
72
  hostname: window.location.hostname,
77
73
  referrer: document.referrer || '',
78
- ref: refRef.current || '',
74
+ ref: ref || getCookie('affiliateo_ref') || '',
79
75
  utm_source: params.get('utm_source') || '',
80
76
  utm_medium: params.get('utm_medium') || '',
81
77
  utm_campaign: params.get('utm_campaign') || '',
@@ -94,55 +90,36 @@ export function AffiliateoProvider({ campaignId, apiUrl, children, }) {
94
90
  }).catch(() => { });
95
91
  }
96
92
  }
97
- // Session cookie — 30 min expiry. Only send session_start if no active session.
98
- const SESSION_COOKIE = 'affiliateo_session';
99
- const hasActiveSession = !!getCookie(SESSION_COOKIE);
100
- if (!hasActiveSession && !sentRef.current) {
93
+ // Send pageview on mount (first load or page navigation)
94
+ if (!sentRef.current) {
101
95
  sentRef.current = true;
102
- send('session_start');
96
+ sendPageview();
103
97
  }
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');
114
- }
115
- window.addEventListener('beforeunload', onLeave);
116
- // On visibility change: refresh session cookie when visible, send session_end after 30 min hidden
117
- let hiddenTimer = null;
118
- function onVisibilityChange() {
119
- if (document.visibilityState === 'hidden') {
120
- // Start a 30-min timer — if user doesn't come back, session is over
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);
98
+ // For SPA: listen for URL changes (popstate + pushState/replaceState)
99
+ let lastPath = window.location.pathname;
100
+ function onUrlChange() {
101
+ if (window.location.pathname !== lastPath) {
102
+ lastPath = window.location.pathname;
103
+ sendPageview();
138
104
  }
139
105
  }
140
- document.addEventListener('visibilitychange', onVisibilityChange);
106
+ // Listen for browser back/forward
107
+ window.addEventListener('popstate', onUrlChange);
108
+ // Patch pushState/replaceState to detect SPA navigations
109
+ const origPushState = history.pushState;
110
+ const origReplaceState = history.replaceState;
111
+ history.pushState = function (...args) {
112
+ origPushState.apply(this, args);
113
+ onUrlChange();
114
+ };
115
+ history.replaceState = function (...args) {
116
+ origReplaceState.apply(this, args);
117
+ onUrlChange();
118
+ };
141
119
  return () => {
142
- window.removeEventListener('beforeunload', onLeave);
143
- document.removeEventListener('visibilitychange', onVisibilityChange);
144
- if (hiddenTimer)
145
- clearTimeout(hiddenTimer);
120
+ window.removeEventListener('popstate', onUrlChange);
121
+ history.pushState = origPushState;
122
+ history.replaceState = origReplaceState;
146
123
  };
147
124
  }, [campaignId, apiBase]);
148
125
  return (_jsx(AffiliateoContext.Provider, { value: state, children: children }));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@affiliateo/web",
3
- "version": "1.5.0",
3
+ "version": "1.5.1",
4
4
  "description": "Affiliateo web SDK — affiliate attribution and session tracking for web apps",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",