/* * Źródło wejścia na www.nolimits.art.pl dla Panelu Kursanta (moje.nolimits.net.pl). * * Panel widzi dziś przy przejściu z www tylko utm_source=www (np. utm_medium=grafik) i nie wie, * czy człowiek przyszedł wcześniej z Google, reklamy Meta czy wprost. Ten skrypt: * 1) przy wejściu na www zapamiętuje źródło: utm_*, gclid/gbraid/wbraid/fbclid, serwer strony * poprzedniej (sam host, bez adresu), stronę lądowania (sama ścieżka) i czas; * reguła: ostatnie wejście nie-bezpośrednie w ciągu 30 dni (wejście wprost nie kasuje * wcześniejszego Google czy reklamy); * 2) przy kliknięciu linku do Panelu (zwykły link, środkowy przycisk, przycisk CMS przez window.open) * dokleja te dane jako nl_src, nl_med, nl_cmp, nl_cnt, nl_trm, nl_ref, nl_lp, nl_ts oraz * gclid/gbraid/wbraid/fbclid. Istniejących parametrów linku (w tym utm_source=www) nie zmienia. * * Bez danych osobowych: tylko parametry kampanii, host strony poprzedniej i ścieżka www. * Pamięć: localStorage tej domeny. Kto odrzucił „Cookies analityczne”, temu nic nie zapisujemy * ani nie doklejamy (jak GTM, który ma tę samą kategorię). */ (function () { 'use strict' var KEY = 'nl_zrodlo' var MAX_AGE_MS = 30 * 24 * 3600 * 1000 var PANEL_HOST = 'moje.nolimits.net.pl' var UTM = { utm_source: 'src', utm_medium: 'med', utm_campaign: 'cmp', utm_content: 'cnt', utm_term: 'trm' } var CLICK_IDS = ['gclid', 'gbraid', 'wbraid', 'fbclid'] var OWN_HOSTS = /(^|\.)nolimits\.(art|net)\.pl$/i var NL_KEYS = ['nl_src', 'nl_med', 'nl_cmp', 'nl_cnt', 'nl_trm', 'nl_ref', 'nl_lp', 'nl_ts'] function analyticsAllowed () { try { var m = document.cookie.match(/(?:^|;\s*)cc_cookie=([^;]*)/) if (!m) return true // tryb opt-out: przed wyborem kategoria analityczna jest włączona var level = JSON.parse(decodeURIComponent(m[1])).level return !Array.isArray(level) || level.indexOf('analytics') !== -1 } catch (e) { return true } } function clip (value, max) { value = String(value == null ? '' : value).trim() return value.length > max ? value.slice(0, max) : value } function read () { try { var touch = JSON.parse(window.localStorage.getItem(KEY) || 'null') if (!touch || typeof touch !== 'object' || !touch.ts || Date.now() - touch.ts * 1000 > MAX_AGE_MS) return null return touch } catch (e) { return null } } function write (touch) { try { window.localStorage.setItem(KEY, JSON.stringify(touch)) } catch (e) {} } function forget () { try { window.localStorage.removeItem(KEY) } catch (e) {} } function currentTouch () { var query = new URLSearchParams(window.location.search) var touch = { ts: Math.floor(Date.now() / 1000), lp: clip(window.location.pathname, 100) } var nonDirect = false // Link oznaczony jako „z www” (utm_source=www, np. skopiowany z grafiku) nie jest źródłem: pomijamy całe utm_*. var ownUtm = String(query.get('utm_source') || '').trim().toLowerCase() === 'www' Object.keys(UTM).forEach(function (name) { var value = ownUtm ? '' : clip(query.get(name), 100) if (value) { touch[UTM[name]] = value nonDirect = true } }) CLICK_IDS.forEach(function (name) { var value = clip(query.get(name), 191) if (value) { touch[name] = value nonDirect = true } }) var host = '' try { host = document.referrer ? new URL(document.referrer).hostname.toLowerCase() : '' } catch (e) {} if (host) { touch.ref = clip(host, 100) // Przejście z własnej strony (powrót z Panelu, przeładowanie www) liczy się jak wejście wprost: // nie zastępuje zapamiętanego Google czy reklamy, ale gdy nic nie ma, Panel dostaje nl_ref // z własnym hostem („z Panelu / ze strony”) zamiast braku źródła. if (!OWN_HOSTS.test(host)) nonDirect = true } touch.direct = !nonDirect return touch } function remember () { if (!analyticsAllowed()) { forget() return } var touch = currentTouch() if (!touch) return var stored = read() if (touch.direct && stored) return // wejście wprost nie zastępuje wcześniejszego źródła delete touch.direct write(touch) } function decorate (url) { try { if (!analyticsAllowed()) return url var touch = read() if (!touch) return url var target = new URL(String(url), window.location.href) if (target.hostname.toLowerCase() !== PANEL_HOST) return url var params = target.searchParams // Link mógł być już ozdobiony (np. prawy przycisk wcześniej): zawsze aktualne źródło, bez dublowania. NL_KEYS.forEach(function (name) { params.delete(name) }) var add = { nl_src: touch.src, nl_med: touch.med, nl_cmp: touch.cmp, nl_cnt: touch.cnt, nl_trm: touch.trm, nl_ref: touch.ref, nl_lp: touch.lp || '/', nl_ts: String(touch.ts) } Object.keys(add).forEach(function (name) { if (add[name]) params.set(name, add[name]) }) CLICK_IDS.forEach(function (name) { if (touch[name] && !params.has(name)) params.set(name, touch[name]) }) var decorated = target.toString() return decorated === new URL(String(url), window.location.href).toString() ? url : decorated } catch (e) { return url } } function onActivate (event) { var link = event.target && event.target.closest ? event.target.closest('a[href]') : null if (!link) return var decorated = decorate(link.href) if (decorated !== link.href) link.href = decorated } remember() document.addEventListener('click', onActivate, true) document.addEventListener('auxclick', onActivate, true) document.addEventListener('contextmenu', onActivate, true) // „Otwórz w nowej karcie” z menu var nativeOpen = window.open if (typeof nativeOpen === 'function') { window.open = function (url) { var args = Array.prototype.slice.call(arguments) if (typeof url === 'string' || url instanceof URL) args[0] = decorate(url) return nativeOpen.apply(window, args) } } window.nlZrodlo = { decorate: decorate, read: read } })()