-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathbase.js
More file actions
148 lines (129 loc) · 4.13 KB
/
base.js
File metadata and controls
148 lines (129 loc) · 4.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
(function () {
// Store script reference for extensions
const script = document.currentScript;
const DUB_ID_VAR = 'dub_id';
const COOKIE_EXPIRES = 90 * 24 * 60 * 60 * 1000; // 90 days
const HOSTNAME = window.location.hostname;
// Common script attributes
const API_HOST = script.getAttribute('data-api-host') || 'https://api.dub.co';
const COOKIE_OPTIONS = (() => {
const defaultOptions = {
domain:
HOSTNAME === 'localhost'
? undefined
: `.${HOSTNAME.replace(/^www\./, '')}`,
path: '/',
sameSite: 'Lax',
expires: new Date(Date.now() + COOKIE_EXPIRES).toUTCString(),
};
const opts = script.getAttribute('data-cookie-options');
if (!opts) return defaultOptions;
const parsedOpts = JSON.parse(opts);
if (parsedOpts.expiresInDays) {
parsedOpts.expires = new Date(
Date.now() + parsedOpts.expiresInDays * 24 * 60 * 60 * 1000,
).toUTCString();
delete parsedOpts.expiresInDays;
}
return { ...defaultOptions, ...parsedOpts };
})();
const DOMAINS_CONFIG = (() => {
// Try to get new JSON domains first
const domainsAttr = script.getAttribute('data-domains');
if (domainsAttr) {
try {
return JSON.parse(domainsAttr);
} catch (e) {
// Fall back to old format if JSON parse fails
}
}
// Backwards compatibility only for data-short-domain
return {
refer: script.getAttribute('data-short-domain'),
};
})();
const SHORT_DOMAIN = DOMAINS_CONFIG.refer;
const ATTRIBUTION_MODEL =
script.getAttribute('data-attribution-model') || 'last-click';
const QUERY_PARAM = script.getAttribute('data-query-param') || 'via';
const QUERY_PARAM_VALUE = new URLSearchParams(location.search).get(
QUERY_PARAM,
);
// Cookie management
const cookieManager = {
get(key) {
return document.cookie
.split(';')
.map((c) => c.trim().split('='))
.find(([k]) => k === key)?.[1];
},
set(key, value) {
const cookieString = Object.entries(COOKIE_OPTIONS)
.filter(([, v]) => v)
.map(([k, v]) => `${k}=${v}`)
.join('; ');
document.cookie = `${key}=${value}; ${cookieString}`;
},
};
let clientClickTracked = false;
// Track click and set cookie
function trackClick(identifier) {
if (clientClickTracked) return;
clientClickTracked = true;
fetch(`${API_HOST}/track/click`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
domain: SHORT_DOMAIN,
key: identifier,
url: window.location.href,
referrer: document.referrer,
}),
})
.then((res) => res.ok && res.json())
.then((data) => {
if (data) {
cookieManager.set(DUB_ID_VAR, data.clickId);
}
});
}
// Initialize tracking
function init() {
const params = new URLSearchParams(location.search);
// Direct click ID in URL
const clickId = params.get(DUB_ID_VAR);
if (clickId) {
cookieManager.set(DUB_ID_VAR, clickId);
// Remove dub_id from URL after setting cookie
params.delete(DUB_ID_VAR);
const newUrl =
window.location.pathname +
(params.toString() ? `?${params.toString()}` : '') +
window.location.hash;
window.history.replaceState({}, document.title, newUrl);
return;
}
// Track via query param
if (QUERY_PARAM_VALUE && SHORT_DOMAIN) {
const existingCookie = cookieManager.get(DUB_ID_VAR);
if (!existingCookie || ATTRIBUTION_MODEL !== 'first-click') {
trackClick(QUERY_PARAM_VALUE);
}
}
}
// Export minimal API with minified names
window._dubAnalytics = {
c: cookieManager, // was cookieManager
i: DUB_ID_VAR, // was DUB_ID_VAR
h: HOSTNAME, // was HOSTNAME
a: API_HOST, // was API_HOST
o: COOKIE_OPTIONS, // was COOKIE_OPTIONS
d: SHORT_DOMAIN, // was SHORT_DOMAIN
m: ATTRIBUTION_MODEL, // was ATTRIBUTION_MODEL
p: QUERY_PARAM, // was QUERY_PARAM
v: QUERY_PARAM_VALUE, // was QUERY_PARAM_VALUE
n: DOMAINS_CONFIG, // was DOMAINS_CONFIG
};
// Initialize
init();
})();