Consent Mode

Respect user privacy choices with consent-aware tracking, cookieless mode, and behavioral modeling.

Consent Mode allows JustAnalytics to respect user privacy choices while still providing useful analytics data. When a user has not yet consented to tracking (or has explicitly denied it), JustAnalytics operates in a restricted mode that collects no cookies, stores no persistent identifiers, and sends only anonymous, aggregated signals.

When consent is later granted, full tracking resumes -- including cookies, session identifiers, and user-level analytics.

This approach ensures compliance with GDPR, CCPA, ePrivacy Directive, and other privacy regulations while minimizing data loss from users who never interact with consent banners.

How It Works#

Consent Mode has two states:

| State | Behavior | |-------|----------| | granted (default) | Full tracking with cookies, session IDs, and complete event data | | denied | No cookies set, no persistent identifiers, cookieless pings with limited data |

When consent is denied, JustAnalytics:

  1. Does not set any first-party cookies
  2. Does not store anything in localStorage or sessionStorage
  3. Sends cookieless pings with only: timestamp, page URL (without query params), viewport size, and a random per-pageview nonce
  4. Does not track returning visitors (no user/session continuity)
  5. Still counts pageviews for aggregate traffic estimation

When consent is granted, JustAnalytics:

  1. Sets a first-party cookie (_ja_id) for visitor identification
  2. Creates a session with full attribution data
  3. Tracks all configured events (pageviews, clicks, custom events, e-commerce)
  4. Applies behavioral modeling to estimate the denied-consent population (see below)

Basic Setup#

Default Granted#

Consent defaults to granted. All features (including session replay, enhanced measurement, and tracing) are active immediately:

<!-- Consent is granted by default -- no attribute needed -->
<script
  defer
  src="https://justanalytics.app/tracker.js"
  data-site-id="YOUR_SITE_ID"
></script>

Overriding to Denied#

For jurisdictions requiring prior consent (GDPR, ePrivacy), start with consent denied:

<script
  defer
  src="https://justanalytics.app/tracker.js"
  data-site-id="YOUR_SITE_ID"
  data-consent="denied"
></script>

Use the JA.updateConsent() method to change consent state after the user interacts with your consent banner:

// User clicks "Accept" on your consent banner
function onAcceptAll() {
  JA.updateConsent('granted');
  // Full tracking begins immediately
  // A new session is created with proper attribution
}

// User clicks "Reject" or "Essential Only"
function onRejectTracking() {
  JA.updateConsent('denied');
  // Cookies are cleared, tracking switches to cookieless mode
}

JustAnalytics does not persist the consent state itself -- that is the responsibility of your consent management platform (CMP). On each page load, set the initial consent state based on your CMP's stored preference:

<script>
  // Read consent state from your CMP before JA loads
  window.__JA_INITIAL_CONSENT = getMyCMPConsent(); // 'granted' or 'denied'
</script>
<script
  defer
  src="https://justanalytics.app/tracker.js"
  data-site-id="YOUR_SITE_ID"
  data-consent="denied"
></script>
// After JA loads, apply the stored consent
document.addEventListener('DOMContentLoaded', () => {
  const stored = window.__JA_INITIAL_CONSENT;
  if (stored === 'granted') {
    JA.updateConsent('granted');
  }
});

Cookieless Tracking Behavior#

When consent is denied, JustAnalytics operates in cookieless mode. This provides limited but useful data:

What is Collected (Denied State)#

| Data Point | Collected | Notes | |------------|-----------|-------| | Pageview count | Yes | Anonymous, no session linking | | Page URL | Yes | Query parameters stripped | | Referrer domain | Yes | Full referrer URL not stored | | Viewport size | Yes | Used for device type estimation | | Country | Yes | Derived from IP, IP not stored | | Timestamp | Yes | Rounded to the hour for privacy | | Browser family | Yes | e.g., "Chrome", not full UA string | | OS family | Yes | e.g., "macOS", not version |

What is NOT Collected (Denied State)#

| Data Point | Reason | |------------|--------| | Visitor ID / cookie | No cookies in denied mode | | Session ID | No session continuity | | Scroll depth | Requires per-page tracking | | Click events | Requires session context | | Custom events | Requires session context | | E-commerce events | Requires session context | | Form interactions | Requires session context | | Full referrer URL | Privacy: only domain retained | | IP address | Never stored (only used for geo lookup) |

Behavioral Modeling#

When a significant portion of your users deny consent, your analytics data has a gap. Behavioral modeling fills this gap by using data from consented users to estimate the behavior of non-consented users.

How It Works#

  1. JustAnalytics receives cookieless pings from denied-consent users (pageview counts, pages visited, referrer domains)
  2. From consented users on the same pages and time periods, it builds behavioral profiles
  3. These profiles are applied proportionally to estimate metrics like bounce rate, session duration, and conversion rate for the denied-consent population
  4. Modeled data is clearly marked in reports with a dashed line or "modeled" badge

Modeled Metrics#

| Metric | Modeling Approach | |--------|-------------------| | Total sessions | Cookieless pageviews / avg. pages-per-session from consented users | | Bounce rate | Applied from consented users on the same page | | Avg. session duration | Applied from consented users with similar page patterns | | Traffic source split | Based on referrer domain distribution from cookieless pings | | Conversion rate | Applied from consented users, adjusted by traffic source |

Accuracy#

Behavioral modeling accuracy depends on your consent rate:

| Consent Rate | Modeling Accuracy | |-------------|-------------------| | 70%+ | High (large sample of consented users) | | 40-70% | Moderate (sufficient sample, some estimation) | | 20-40% | Low (limited sample, higher variance) | | < 20% | Very low (too few consented users to model reliably) |

Note: Modeled data is always an estimate. Reports clearly indicate when numbers include modeled data so you can assess confidence levels.

Enabling/Disabling Modeling#

Behavioral modeling is enabled by default. To disable it:

  1. Navigate to Settings > Privacy
  2. Toggle Behavioral Modeling off
  3. Reports will only show data from consented users

GDPR Compliance#

Lawful Basis#

Under GDPR, analytics tracking typically requires consent (Article 6(1)(a)). JustAnalytics Consent Mode supports this by:

  • Defaulting to denied until explicit consent is obtained
  • Collecting only anonymous, non-personal data in denied mode
  • Never storing IP addresses (used only for real-time geo lookup, then discarded)
  • Supporting the right to withdraw consent via JA.updateConsent('denied')

Data Processing Agreement#

JustAnalytics acts as a data processor under GDPR. A Data Processing Agreement (DPA) is available at justanalytics.app/legal/dpa.

Data Retention#

Configure data retention in Settings > Data Retention:

  • Analytics events: 14 days to 25 months (default: 14 months)
  • Session replay: 7 to 90 days (default: 30 days)
  • Cookieless pings: 7 to 90 days (default: 30 days)

CCPA Compliance#

For California Consumer Privacy Act compliance:

  1. Do Not Sell: JustAnalytics does not sell user data to third parties
  2. Opt-Out: Support the "Do Not Sell My Personal Information" link by calling JA.updateConsent('denied')
  3. Global Privacy Control: JustAnalytics automatically detects the Sec-GPC: 1 header and navigator.globalPrivacyControl and treats them as denied
// Automatic GPC detection -- no code needed
// JustAnalytics checks navigator.globalPrivacyControl on load
// If true, consent defaults to 'denied' regardless of data-consent attribute

OneTrust#

// OneTrust callback when consent changes
function OptanonWrapper() {
  const activeGroups = OnetrustActiveGroups || '';

  if (activeGroups.includes('C0002')) {
    // Performance cookies accepted
    JA.updateConsent('granted');
  } else {
    JA.updateConsent('denied');
  }
}
<!-- Load JA with denied default, OneTrust will grant if appropriate -->
<script
  defer
  src="https://justanalytics.app/tracker.js"
  data-site-id="YOUR_SITE_ID"
  data-consent="denied"
></script>

CookieYes#

// CookieYes event listener
document.addEventListener('cookieyes_consent_update', function(event) {
  const consent = event.detail;

  if (consent.analytics === 'yes') {
    JA.updateConsent('granted');
  } else {
    JA.updateConsent('denied');
  }
});

Cookiebot#

// Cookiebot callback
window.addEventListener('CookiebotOnAccept', function() {
  if (Cookiebot.consent.statistics) {
    JA.updateConsent('granted');
  }
});

window.addEventListener('CookiebotOnDecline', function() {
  JA.updateConsent('denied');
});
// Your custom consent banner logic
const consentBanner = document.getElementById('consent-banner');
const acceptBtn = document.getElementById('accept-cookies');
const rejectBtn = document.getElementById('reject-cookies');

acceptBtn.addEventListener('click', () => {
  localStorage.setItem('ja_consent', 'granted');
  JA.updateConsent('granted');
  consentBanner.style.display = 'none';
});

rejectBtn.addEventListener('click', () => {
  localStorage.setItem('ja_consent', 'denied');
  JA.updateConsent('denied');
  consentBanner.style.display = 'none';
});

// On page load, restore previous consent choice
document.addEventListener('DOMContentLoaded', () => {
  const stored = localStorage.getItem('ja_consent');
  if (stored === 'granted') {
    JA.updateConsent('granted');
    consentBanner.style.display = 'none';
  } else if (stored === 'denied') {
    consentBanner.style.display = 'none';
  }
  // If no stored preference, banner remains visible
});

Consent mode also applies to the monitor script (error tracking, session replay). Since session replay is on by default, use data-consent="denied" for GDPR regions to gate recording on consent:

<script
  defer
  src="https://justanalytics.app/monitor.js"
  data-site-id="YOUR_SITE_ID"
  data-consent="denied"
></script>

When consent is denied:

  • Error tracking operates in anonymous mode (errors captured without session context)
  • Session replay is disabled entirely
  • Web Vitals are captured anonymously

When consent is granted:

  • Full session replay recording begins
  • Errors are linked to sessions and users
  • Web Vitals are correlated with user behavior

Verify Denied State#

  1. Set data-consent="denied" on your tracking script
  2. Open browser DevTools > Application > Cookies
  3. Verify no _ja_id cookie is set
  4. Check Network tab: requests to /api/track should have consent: denied in the payload
  5. Check your dashboard: anonymous pageviews should still be counted

Verify Granted State#

  1. Call JA.updateConsent('granted') in the console
  2. Verify _ja_id cookie appears in Application > Cookies
  3. Check Network tab: subsequent requests should have consent: granted and full event data
  4. Check your dashboard: session should appear with full attribution
  1. Call JA.updateConsent('denied') in the console
  2. Verify _ja_id cookie is removed
  3. Subsequent pageviews should be cookieless pings

Next Steps#