Switch Tianji tracking from opt-in consent to acknowledge notice.

Load analytics on page load so visitors who never interact still produce data, while an informational banner lets users acknowledge the practice. Migrate legacy declined and accepted consent values so prior opt-outs are cleared and tracking resumes.

Closes #7
This commit is contained in:
2026-07-02 11:52:20 +00:00
parent 846f1b8a37
commit 351994673a
@@ -1,7 +1,9 @@
(function () {
'use strict';
var CONSENT_KEY = 'aiml_analytics_consent';
var NOTICE_KEY = 'aiml_analytics_notice';
var LEGACY_CONSENT_KEY = 'aiml_analytics_consent';
var LEGACY_DISABLED_KEY = 'tianji.disabled';
var configEl = document.getElementById('tianji-config');
if (!configEl) {
return;
@@ -10,19 +12,26 @@
var trackerUrl = configEl.dataset.trackerUrl;
var websiteId = configEl.dataset.websiteId;
var userId = configEl.dataset.userId || '';
var pendingConsentEvent = false;
function getConsent() {
function getStorageItem(key) {
try {
return localStorage.getItem(CONSENT_KEY);
return localStorage.getItem(key);
} catch (e) {
return null;
}
}
function setConsent(value) {
function setStorageItem(key, value) {
try {
localStorage.setItem(CONSENT_KEY, value);
localStorage.setItem(key, value);
} catch (e) {
/* ignore storage errors */
}
}
function removeStorageItem(key) {
try {
localStorage.removeItem(key);
} catch (e) {
/* ignore storage errors */
}
@@ -71,51 +80,44 @@
script.onload = function () {
identifyUser();
if (pendingConsentEvent) {
trackEvent('consent_accepted');
pendingConsentEvent = false;
}
document.dispatchEvent(new CustomEvent('tianji:ready'));
};
document.head.appendChild(script);
}
function acceptTracking() {
setConsent('accepted');
hideBanner();
try {
localStorage.removeItem('tianji.disabled');
} catch (e) {
/* ignore storage errors */
function migrateLegacyConsent() {
var legacyConsent = getStorageItem(LEGACY_CONSENT_KEY);
var legacyDisabled = getStorageItem(LEGACY_DISABLED_KEY);
if (legacyConsent === 'accepted') {
setStorageItem(NOTICE_KEY, 'acknowledged');
removeStorageItem(LEGACY_CONSENT_KEY);
removeStorageItem(LEGACY_DISABLED_KEY);
return 'migrated_acknowledged';
}
pendingConsentEvent = true;
loadTracker();
if (legacyConsent === 'declined' || legacyDisabled === '1') {
removeStorageItem(LEGACY_CONSENT_KEY);
removeStorageItem(LEGACY_DISABLED_KEY);
return 'migrated_declined';
}
return null;
}
function declineTracking() {
setConsent('declined');
function acknowledgeNotice() {
setStorageItem(NOTICE_KEY, 'acknowledged');
hideBanner();
try {
localStorage.setItem('tianji.disabled', '1');
} catch (e) {
/* ignore storage errors */
}
if (window.aimlTrack) {
window.aimlTrack('consent_declined');
}
window.aimlTrackWhenReady('notice_acknowledged');
}
function bindBannerControls() {
var acceptBtn = document.getElementById('cookie-consent-accept');
var declineBtn = document.getElementById('cookie-consent-decline');
var acknowledgeBtn = document.getElementById('cookie-consent-acknowledge');
var manageLinks = document.querySelectorAll('[data-open-cookie-preferences]');
if (acceptBtn) {
acceptBtn.addEventListener('click', acceptTracking);
}
if (declineBtn) {
declineBtn.addEventListener('click', declineTracking);
if (acknowledgeBtn) {
acknowledgeBtn.addEventListener('click', acknowledgeNotice);
}
manageLinks.forEach(function (link) {
link.addEventListener('click', function (event) {
@@ -140,16 +142,14 @@
});
};
function initConsent() {
function initNotice() {
bindBannerControls();
loadTracker();
var consent = getConsent();
if (consent === 'accepted') {
hideBanner();
loadTracker();
return;
}
if (consent === 'declined') {
var migration = migrateLegacyConsent();
var notice = getStorageItem(NOTICE_KEY);
if (notice === 'acknowledged' || migration === 'migrated_acknowledged') {
hideBanner();
return;
}
@@ -157,5 +157,5 @@
showBanner();
}
initConsent();
initNotice();
})();