gate locale behind functional consent
This commit is contained in:
Vendored
+31
-2
@@ -1,9 +1,22 @@
|
||||
'use client';
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import { LOCALE_COOKIE_NAME } from '../i18n/index.js';
|
||||
import { ACCEPT_ALL_CONSENT, DEFAULT_CONSENT, REJECT_ALL_CONSENT } from './categories.js';
|
||||
import { updateConsent } from './googleConsent.js';
|
||||
import { CONSENT_COOKIE, CONSENT_MAX_AGE, parseConsent, serializeConsent } from './storage.js';
|
||||
export function useConsent() {
|
||||
/**
|
||||
* Cookies to delete when consent for a category is withdrawn. Keyed by
|
||||
* category. The plugin knows about its own functional cookie (locale); clients
|
||||
* can extend this via the `cookieMap` arg to useConsent if they set their own.
|
||||
*/ const DEFAULT_COOKIE_MAP = {
|
||||
functional: [
|
||||
LOCALE_COOKIE_NAME
|
||||
]
|
||||
};
|
||||
/** Expire a cookie now, across the whole site. */ function deleteCookie(name) {
|
||||
document.cookie = `${name}=;path=/;max-age=0;samesite=lax`;
|
||||
}
|
||||
export function useConsent(cookieMap = DEFAULT_COOKIE_MAP) {
|
||||
const [state, setState] = useState(DEFAULT_CONSENT);
|
||||
const [decided, setDecided] = useState(false);
|
||||
useEffect(()=>{
|
||||
@@ -15,6 +28,19 @@ export function useConsent() {
|
||||
}
|
||||
}, []);
|
||||
const persist = useCallback((next)=>{
|
||||
// Withdrawal cleanup: for any category flipping true → false, delete the
|
||||
// cookies tied to it. GDPR: withdrawing consent must stop the processing,
|
||||
// so a functional cookie (e.g. locale) written under consent has to go when
|
||||
// that consent is revoked. Uses the current `state` as the previous value.
|
||||
for (const cat of Object.keys(cookieMap)){
|
||||
const wasGranted = state[cat] === true;
|
||||
const nowDenied = next[cat] !== true;
|
||||
if (wasGranted && nowDenied) {
|
||||
for (const name of cookieMap[cat] ?? []){
|
||||
deleteCookie(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
document.cookie = `${CONSENT_COOKIE}=${serializeConsent(next)};path=/;max-age=${CONSENT_MAX_AGE};samesite=lax`;
|
||||
setState(next);
|
||||
setDecided(true);
|
||||
@@ -23,7 +49,10 @@ export function useConsent() {
|
||||
// the rest of the session and never write their cookies — the banner would
|
||||
// look like it worked while nothing changed.
|
||||
updateConsent(next);
|
||||
}, []);
|
||||
}, [
|
||||
state,
|
||||
cookieMap
|
||||
]);
|
||||
const acceptAll = useCallback(()=>persist(ACCEPT_ALL_CONSENT), [
|
||||
persist
|
||||
]);
|
||||
|
||||
Reference in New Issue
Block a user