Consent Mode
Respect user privacy choices with consent-aware tracking, cookieless mode, and behavioral modeling.
What is Consent Mode?#
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:
- Does not set any first-party cookies
- Does not store anything in localStorage or sessionStorage
- Sends cookieless pings with only: timestamp, page URL (without query params), viewport size, and a random per-pageview nonce
- Does not track returning visitors (no user/session continuity)
- Still counts pageviews for aggregate traffic estimation
When consent is granted, JustAnalytics:
- Sets a first-party cookie (
_ja_id) for visitor identification - Creates a session with full attribution data
- Tracks all configured events (pageviews, clicks, custom events, e-commerce)
- 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>
Updating Consent at Runtime#
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
}
Consent Persistence#
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#
- JustAnalytics receives cookieless pings from denied-consent users (pageview counts, pages visited, referrer domains)
- From consented users on the same pages and time periods, it builds behavioral profiles
- These profiles are applied proportionally to estimate metrics like bounce rate, session duration, and conversion rate for the denied-consent population
- 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:
- Navigate to Settings > Privacy
- Toggle Behavioral Modeling off
- 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
denieduntil 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:
- Do Not Sell: JustAnalytics does not sell user data to third parties
- Opt-Out: Support the "Do Not Sell My Personal Information" link by calling
JA.updateConsent('denied') - Global Privacy Control: JustAnalytics automatically detects the
Sec-GPC: 1header andnavigator.globalPrivacyControland treats them asdenied
// Automatic GPC detection -- no code needed
// JustAnalytics checks navigator.globalPrivacyControl on load
// If true, consent defaults to 'denied' regardless of data-consent attribute
Integration with Cookie Consent Banners#
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');
});
Custom Consent Banner#
// 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
});
Monitor.js Consent#
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
Testing Consent Mode#
Verify Denied State#
- Set
data-consent="denied"on your tracking script - Open browser DevTools > Application > Cookies
- Verify no
_ja_idcookie is set - Check Network tab: requests to
/api/trackshould haveconsent: deniedin the payload - Check your dashboard: anonymous pageviews should still be counted
Verify Granted State#
- Call
JA.updateConsent('granted')in the console - Verify
_ja_idcookie appears in Application > Cookies - Check Network tab: subsequent requests should have
consent: grantedand full event data - Check your dashboard: session should appear with full attribution
Verify Consent Withdrawal#
- Call
JA.updateConsent('denied')in the console - Verify
_ja_idcookie is removed - Subsequent pageviews should be cookieless pings
Next Steps#
- Session Replay Privacy -- privacy controls specific to replay
- Web Analytics Tracking -- full tracking script reference
- E-Commerce Tracking -- e-commerce events and consent