Skip to content

Commit e71827f

Browse files
committed
Implement granular consent system with mandatory AdSense
- Advertising cookies are mandatory and cannot be rejected (required for AdSense) - Analytics, functional, and personalization cookies are customizable - Users must explicitly choose consent preferences - Google Consent Mode defaults updated to reflect mandatory advertising - Accept All: grants all consent types - Reject All: rejects non-essential cookies but keeps AdSense enabled - Customize: allows granular control over each consent type - Build successful with 52 pages generated
1 parent a456eed commit e71827f

File tree

2 files changed

+96
-34
lines changed

2 files changed

+96
-34
lines changed

src/components/bases/head.astro

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,20 +50,22 @@ const OGImage = new URL(meta.ogImage, Astro.url).href;
5050
<>
5151
<script async src={`https://www.googletagmanager.com/gtag/js?id=${GOOGLE_CONFIG.GA_MEASUREMENT_ID}`}></script>
5252
<script is:inline define:vars={{ gaId: GOOGLE_CONFIG.GA_MEASUREMENT_ID }}>
53+
// Set default consent state BEFORE loading gtag
5354
window.dataLayer = window.dataLayer || [];
5455
function gtag(){dataLayer.push(arguments);}
55-
gtag('js', new Date());
5656

57-
// Set default consent state (granted by default)
57+
// Set default consent state - advertising is mandatory, others denied until user chooses
5858
gtag('consent', 'default', {
59-
'ad_storage': 'granted',
60-
'ad_user_data': 'granted',
61-
'ad_personalization': 'granted',
62-
'analytics_storage': 'granted',
63-
'functionality_storage': 'granted',
64-
'security_storage': 'granted'
59+
'ad_storage': 'granted', // Always granted for AdSense
60+
'ad_user_data': 'granted', // Always granted for AdSense
61+
'ad_personalization': 'granted', // Always granted for AdSense
62+
'analytics_storage': 'denied',
63+
'functionality_storage': 'denied',
64+
'security_storage': 'denied',
65+
'personalization_storage': 'denied'
6566
});
6667

68+
gtag('js', new Date());
6769
gtag('config', gaId);
6870
</script>
6971
</>

src/components/shared/cookie-consent.astro

Lines changed: 86 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@
6464
<h4 class="font-medium text-base-content mb-3">
6565
Choose your preferences:
6666
</h4>
67-
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
67+
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
6868
<div class="flex items-start gap-3">
6969
<input
7070
type="checkbox"
@@ -106,20 +106,35 @@
106106
type="checkbox"
107107
id="functional-cookies"
108108
class="checkbox checkbox-sm"
109-
checked
110-
disabled
111109
/>
112110
<div>
113111
<label
114112
for="functional-cookies"
115-
class="font-medium text-sm cursor-pointer opacity-60"
116-
>Functional Cookies (Required)</label
113+
class="font-medium text-sm cursor-pointer"
114+
>Functional Cookies</label
117115
>
118116
<p class="text-xs text-base-content/60 mt-1">
119117
Essential for website functionality and your preferences
120118
</p>
121119
</div>
122120
</div>
121+
<div class="flex items-start gap-3">
122+
<input
123+
type="checkbox"
124+
id="personalization-cookies"
125+
class="checkbox checkbox-sm"
126+
/>
127+
<div>
128+
<label
129+
for="personalization-cookies"
130+
class="font-medium text-sm cursor-pointer"
131+
>Personalization Cookies</label
132+
>
133+
<p class="text-xs text-base-content/60 mt-1">
134+
Remember your preferences and customize your experience
135+
</p>
136+
</div>
137+
</div>
123138
</div>
124139
<div class="flex justify-end gap-2 mt-4">
125140
<button id="cancel-customize" class="btn btn-ghost btn-sm">
@@ -159,20 +174,14 @@
159174
const consent = this.getCookieConsent();
160175

161176
if (!consent) {
162-
// Apply default consent (all granted)
163-
const defaultConsent = {
164-
analytics: true,
165-
advertising: true,
166-
functional: true,
167-
timestamp: Date.now(),
168-
};
169-
this.applyConsent(defaultConsent);
177+
// Show banner for first-time users - no default consent applied
178+
this.showBanner();
170179
} else {
171180
// Apply existing preferences
172181
this.applyConsent(consent);
173182
}
174183

175-
// Always setup event listeners (for customize functionality)
184+
// Always setup event listeners
176185
this.setupEventListeners();
177186
}
178187

@@ -198,8 +207,9 @@
198207
acceptBtn.addEventListener("click", () => {
199208
const consent = {
200209
analytics: true,
201-
advertising: true, // Always true for AdSense
202-
functional: true, // Always true for functionality
210+
advertising: true, // Always true for AdSense (mandatory)
211+
functional: true,
212+
personalization: true,
203213
timestamp: Date.now(),
204214
};
205215
this.saveConsent(consent);
@@ -208,14 +218,15 @@
208218
});
209219
}
210220

211-
// Reject all cookies (but advertising and functional remain enabled)
221+
// Reject non-essential cookies (advertising remains enabled)
212222
const rejectBtn = document.getElementById("reject-cookies");
213223
if (rejectBtn) {
214224
rejectBtn.addEventListener("click", () => {
215225
const consent = {
216-
analytics: false, // Only reject analytics
217-
advertising: true, // Keep ads enabled
218-
functional: true, // Keep functional enabled
226+
analytics: false,
227+
advertising: true, // Always true for AdSense (mandatory)
228+
functional: false,
229+
personalization: false,
219230
timestamp: Date.now(),
220231
};
221232
this.saveConsent(consent);
@@ -270,11 +281,21 @@
270281
const analyticsCheckbox = document.getElementById(
271282
"analytics-cookies"
272283
) as HTMLInputElement;
284+
const advertisingCheckbox = document.getElementById(
285+
"advertising-cookies"
286+
) as HTMLInputElement;
287+
const functionalCheckbox = document.getElementById(
288+
"functional-cookies"
289+
) as HTMLInputElement;
290+
const personalizationCheckbox = document.getElementById(
291+
"personalization-cookies"
292+
) as HTMLInputElement;
273293

274294
const consent = {
275295
analytics: analyticsCheckbox?.checked ?? false,
276296
advertising: true, // Always true for AdSense (mandatory)
277-
functional: true, // Always true for functionality (mandatory)
297+
functional: functionalCheckbox?.checked ?? false,
298+
personalization: personalizationCheckbox?.checked ?? false,
278299
timestamp: Date.now(),
279300
};
280301
this.saveConsent(consent);
@@ -294,18 +315,29 @@
294315
}
295316

296317
applyConsent(consent: any) {
297-
// Handle Google AdSense consent (always enabled for mandatory advertising)
318+
// Handle advertising consent (always enabled for AdSense)
298319
this.enableAdSense();
299320

300-
// Handle analytics
321+
// Handle analytics consent
301322
if (consent.analytics) {
302323
this.enableAnalytics();
303324
} else {
304325
this.disableAnalytics();
305326
}
306327

307-
// Functional cookies are always enabled for basic functionality
308-
this.enableFunctional();
328+
// Handle functional consent
329+
if (consent.functional) {
330+
this.enableFunctional();
331+
} else {
332+
this.disableFunctional();
333+
}
334+
335+
// Handle personalization consent
336+
if (consent.personalization) {
337+
this.enablePersonalization();
338+
} else {
339+
this.disablePersonalization();
340+
}
309341
}
310342

311343
enableAdSense() {
@@ -349,14 +381,42 @@
349381
}
350382

351383
enableFunctional() {
352-
// Functional cookies are always enabled
384+
// Enable functional cookies
353385
if (typeof gtag !== "undefined") {
354386
gtag("consent", "update", {
355387
functionality_storage: "granted",
356388
security_storage: "granted",
357389
});
358390
}
359391
}
392+
393+
disableFunctional() {
394+
// Disable functional cookies
395+
if (typeof gtag !== "undefined") {
396+
gtag("consent", "update", {
397+
functionality_storage: "denied",
398+
security_storage: "denied",
399+
});
400+
}
401+
}
402+
403+
enablePersonalization() {
404+
// Enable personalization cookies
405+
if (typeof gtag !== "undefined") {
406+
gtag("consent", "update", {
407+
personalization_storage: "granted",
408+
});
409+
}
410+
}
411+
412+
disablePersonalization() {
413+
// Disable personalization cookies
414+
if (typeof gtag !== "undefined") {
415+
gtag("consent", "update", {
416+
personalization_storage: "denied",
417+
});
418+
}
419+
}
360420
}
361421

362422
// Initialize cookie consent when DOM is loaded

0 commit comments

Comments
 (0)