Skip to content

Commit 31dbe22

Browse files
authored
Merge pull request #58 from dubinc/outbound-iframes
Include iframe URLs in outbound domains updating
2 parents b4e5081 + 1ee231d commit 31dbe22

File tree

1 file changed

+59
-20
lines changed

1 file changed

+59
-20
lines changed

packages/script/src/extensions/outbound-domains.js

Lines changed: 59 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,36 +8,75 @@ const initOutboundDomains = () => {
88
} = window._dubAnalytics;
99
let outboundLinksUpdated = new Set(); // Track processed links
1010

11+
function normalizeDomain(domain) {
12+
return domain.replace(/^www\./, '').trim();
13+
}
14+
15+
function isMatchingDomain(url, domain) {
16+
try {
17+
const urlHostname = new URL(url).hostname;
18+
const normalizedUrlHostname = normalizeDomain(urlHostname);
19+
const normalizedDomain = normalizeDomain(domain);
20+
21+
// Exact match after removing www.
22+
return normalizedUrlHostname === normalizedDomain;
23+
} catch (e) {
24+
return false;
25+
}
26+
}
27+
1128
function addOutboundTracking(clickId) {
12-
// Parse comma-separated outbound domains
13-
const outboundDomains = DOMAINS_CONFIG.outbound
14-
?.split(',')
15-
.map((d) => d.trim());
29+
// Handle both string and array configurations for outbound domains
30+
const outboundDomains = Array.isArray(DOMAINS_CONFIG.outbound)
31+
? DOMAINS_CONFIG.outbound
32+
: DOMAINS_CONFIG.outbound?.split(',').map((d) => d.trim());
33+
1634
if (!outboundDomains?.length) return;
1735

18-
const currentDomain = HOSTNAME.replace(/^www\./, '');
19-
const filteredDomains = outboundDomains.filter((d) => d !== currentDomain);
36+
const currentDomain = normalizeDomain(HOSTNAME);
37+
const filteredDomains = outboundDomains
38+
.map(normalizeDomain)
39+
.filter((d) => d !== currentDomain);
2040

2141
const existingCookie = clickId || cookieManager.get(DUB_ID_VAR);
2242
if (!existingCookie) return;
2343

24-
const selector = filteredDomains
25-
.map((domain) => `a[href*="${domain}"]`)
26-
.join(',');
44+
// Get all links and iframes
45+
const elements = document.querySelectorAll('a[href], iframe[src]');
46+
if (!elements || elements.length === 0) return;
2747

28-
const links = document.querySelectorAll(selector);
29-
if (!links || links.length === 0) return;
30-
31-
links.forEach((link) => {
32-
// Skip already processed links
33-
if (outboundLinksUpdated.has(link)) return;
48+
elements.forEach((element) => {
49+
// Skip already processed elements
50+
if (outboundLinksUpdated.has(element)) return;
3451

3552
try {
36-
const url = new URL(link.href);
37-
url.searchParams.set(DUB_ID_VAR, existingCookie);
38-
link.href = url.toString();
39-
outboundLinksUpdated.add(link);
40-
} catch (e) {}
53+
const urlString = element.href || element.src;
54+
if (!urlString) return;
55+
56+
// Check if the URL matches any of our outbound domains
57+
const isOutbound = filteredDomains.some((domain) =>
58+
isMatchingDomain(urlString, domain),
59+
);
60+
if (!isOutbound) return;
61+
62+
const url = new URL(urlString);
63+
64+
// Only add the tracking parameter if it's not already present
65+
if (!url.searchParams.has(DUB_ID_VAR)) {
66+
url.searchParams.set(DUB_ID_VAR, existingCookie);
67+
68+
// Update the appropriate attribute based on element type
69+
if (element.tagName.toLowerCase() === 'a') {
70+
element.href = url.toString();
71+
} else if (element.tagName.toLowerCase() === 'iframe') {
72+
element.src = url.toString();
73+
}
74+
75+
outboundLinksUpdated.add(element);
76+
}
77+
} catch (e) {
78+
console.error('Error processing element:', e);
79+
}
4180
});
4281
}
4382

0 commit comments

Comments
 (0)