Skip to content

Commit e0fd227

Browse files
committed
Replace Cookiebot with Usercentrics
1 parent 0194536 commit e0fd227

File tree

5 files changed

+86
-65
lines changed

5 files changed

+86
-65
lines changed

docs/.vuepress/client.ts

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ const findEsMeta = (route: RouteLocationNormalized) => {
5151

5252
const removeHtml = (path: string) => path.replace(".html", "");
5353

54-
let cookiebotListenerRegistered = false;
54+
let usercentricsConsentListenerRegistered = false;
5555

5656

5757
export default defineClientConfig({
@@ -62,8 +62,8 @@ export default defineClientConfig({
6262
const { hasConsent, posthog } = usePostHog();
6363
useReoDev();
6464

65-
const captureEvent = (event: string, properties?: Record<string, any>) => {
66-
if (!hasConsent()) return;
65+
const captureEvent = async (event: string, properties?: Record<string, any>) => {
66+
if (!await hasConsent()) return;
6767
try {
6868
posthog.capture(event, properties);
6969
} catch (error) {
@@ -114,21 +114,21 @@ export default defineClientConfig({
114114
handlePageLeave(to, from)
115115
});
116116

117-
// Capture first pageview immediately after user accepts statistics cookies
118-
if (typeof window !== "undefined" && !cookiebotListenerRegistered) {
119-
cookiebotListenerRegistered = true;
120-
window.addEventListener("CookiebotOnAccept", () => {
121-
if (!hasConsent()) return;
122-
117+
// Capture first pageview when consent is given (UC_CONSENT) or when CMP is ready with existing consent (UC_UI_INITIALIZED)
118+
if (typeof window !== "undefined" && !usercentricsConsentListenerRegistered) {
119+
usercentricsConsentListenerRegistered = true;
120+
const capturePageViewOnConsent = async () => {
121+
if (!await hasConsent()) return;
123122
const to = router.currentRoute.value;
124123
const esData = findEsMeta(to);
125-
126124
captureEvent("$pageview", {
127125
site: "docs",
128126
version: esData?.version,
129127
category: esData?.category,
130-
});
131-
});
128+
});
129+
};
130+
window.addEventListener("UC_CONSENT", capturePageViewOnConsent);
131+
window.addEventListener("UC_UI_INITIALIZED", capturePageViewOnConsent);
132132
}
133133

134134

docs/.vuepress/config.ts

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -81,20 +81,11 @@ export default defineUserConfig({
8181
},
8282
theme: hopeTheme(themeOptions, {custom: true}),
8383
head: [
84-
// Cookiebot banner
84+
// Usercentrics CMP
8585
['script', {
86-
id: 'Cookiebot',
87-
src: 'https://consent.cookiebot.com/uc.js',
88-
'data-cbid': 'ee971b30-e872-46e8-b421-706ef26d9dcc',
89-
'data-blockingmode': 'manual',
90-
type: 'text/javascript',
91-
}],
92-
93-
// Cookiebot declaration
94-
['script', {
95-
id: 'CookieDeclaration',
96-
src: 'https://consent.cookiebot.com/ee971b30-e872-46e8-b421-706ef26d9dcc/cd.js',
97-
type: 'text/javascript',
86+
id: 'usercentrics-cmp',
87+
src: 'https://web.cmp.usercentrics.eu/ui/loader.js',
88+
'data-settings-id': 'ArWRikBAz-iKhj',
9889
async: true,
9990
}],
10091

docs/.vuepress/lib/consent.ts

Lines changed: 39 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,47 @@
1-
// Type declarations for Cookiebot
1+
// Usercentrics Browser UI API (getServices was removed; use getServicesBaseInfo)
2+
// https://usercentrics.com/docs/web/features/v2/browser_ui_api/browser_ui_api/#getservices
3+
24
declare global {
35
interface Window {
4-
Cookiebot?: {
5-
consent?: {
6-
necessary?: boolean;
7-
preferences?: boolean;
8-
statistics?: boolean;
9-
marketing?: boolean;
10-
};
11-
renew?: () => void;
12-
withdraw?: () => void;
6+
UC_UI?: {
7+
getServicesBaseInfo?: () => Promise<Array<{
8+
id: string;
9+
categorySlug: string;
10+
consent: { status: boolean };
11+
}>>;
12+
isInitialized?: () => boolean;
1313
};
1414
}
1515
}
1616

17-
/**
18-
* Checks if the user has given consent for statistics cookies.
19-
* This is used for analytics tools like PostHog and Reo.dev.
20-
*/
21-
export function hasStatisticsConsent(): boolean {
17+
async function hasConsentForCategory(categorySlug: string): Promise<boolean> {
2218
if (typeof window === "undefined") return false;
23-
return window.Cookiebot?.consent?.statistics === true;
19+
const ui = window.UC_UI;
20+
21+
if (!ui?.getServicesBaseInfo) {
22+
return false;
23+
}
24+
25+
try {
26+
const services = await ui.getServicesBaseInfo();
27+
28+
if (!Array.isArray(services)) return false;
29+
30+
return services.some(
31+
(s) => s.categorySlug.toLowerCase() === categorySlug.toLowerCase() && s.consent?.status === true
32+
);
33+
} catch (e) {
34+
console.error("[Consent] Error checking consent:", e);
35+
return false;
36+
}
37+
}
38+
39+
/** PostHog uses the functional category in Usercentrics. */
40+
export function hasFunctionalConsent(): Promise<boolean> {
41+
return hasConsentForCategory("functional");
42+
}
43+
44+
/** Reo.dev uses the marketing category in Usercentrics. */
45+
export function hasMarketingConsent(): Promise<boolean> {
46+
return hasConsentForCategory("marketing");
2447
}

docs/.vuepress/lib/usePosthog.ts

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import posthog from "posthog-js";
2-
import { hasStatisticsConsent } from "./consent";
2+
import { hasFunctionalConsent } from "./consent";
33

44
const POSTHOG_CONFIG = {
55
apiKey: "phc_DeHBgHGersY4LmDlADnPrsCPOAmMO7QFOH8f4DVEVmD",
@@ -48,37 +48,35 @@ function setupConsentListeners(): void {
4848
if (listenersRegistered) return;
4949
listenersRegistered = true;
5050

51-
window.addEventListener("CookiebotOnAccept", () => {
52-
if (hasStatisticsConsent()) {
51+
const applyConsent = async () => {
52+
if (await hasFunctionalConsent()) {
5353
resumeTracking();
5454
} else {
5555
stopTracking();
5656
}
57-
});
57+
};
5858

59-
window.addEventListener("CookiebotOnDecline", () => {
60-
stopTracking();
59+
window.addEventListener("UC_CONSENT", () => {
60+
applyConsent();
6161
});
6262

63-
window.addEventListener("CookiebotOnConsentReady", () => {
64-
if (hasStatisticsConsent()) {
65-
resumeTracking();
66-
} else {
67-
stopTracking();
68-
}
63+
window.addEventListener("UC_UI_INITIALIZED", () => {
64+
applyConsent();
6965
});
7066
}
7167

7268
export function usePostHog() {
7369
if (typeof window !== "undefined") {
7470
setupConsentListeners();
75-
if (hasStatisticsConsent()) {
76-
initializePostHog();
77-
}
71+
hasFunctionalConsent().then((consented) => {
72+
if (consented) {
73+
initializePostHog();
74+
}
75+
});
7876
}
7977

8078
return {
8179
posthog,
82-
hasConsent: hasStatisticsConsent,
80+
hasConsent: hasFunctionalConsent,
8381
};
8482
}

docs/.vuepress/lib/useReoDev.ts

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { loadReoScript } from "reodotdev";
2-
import { hasStatisticsConsent } from "./consent";
2+
import { hasMarketingConsent } from "./consent";
33

44
let listenersRegistered = false;
55
let isInitialized = false;
@@ -67,7 +67,7 @@ function stopReoDev(): void {
6767

6868
async function initializeReoDev(): Promise<void> {
6969
if (typeof window === "undefined") return;
70-
if (!hasStatisticsConsent()) return;
70+
if (!await hasMarketingConsent()) return;
7171
if (isInitialized || reoInstance || reoPromise || typeof window.Reo !== 'undefined') return;
7272

7373
try {
@@ -84,18 +84,27 @@ async function initializeReoDev(): Promise<void> {
8484
}
8585

8686
function applyConsentState(): void {
87-
if (hasStatisticsConsent()) void initializeReoDev();
88-
else stopReoDev();
87+
hasMarketingConsent().then((consented) => {
88+
if (consented) {
89+
void initializeReoDev();
90+
} else {
91+
stopReoDev();
92+
}
93+
});
8994
}
9095

9196
function setupConsentListeners(): void {
9297
if (typeof window === "undefined") return;
9398
if (listenersRegistered) return;
9499
listenersRegistered = true;
95100

96-
window.addEventListener("CookiebotOnAccept", applyConsentState);
97-
window.addEventListener("CookiebotOnDecline", applyConsentState);
98-
window.addEventListener("CookiebotOnConsentReady", applyConsentState);
101+
window.addEventListener("UC_CONSENT", () => {
102+
applyConsentState();
103+
});
104+
105+
window.addEventListener("UC_UI_INITIALIZED", () => {
106+
applyConsentState();
107+
});
99108
}
100109

101110
export function useReoDev() {
@@ -105,7 +114,7 @@ export function useReoDev() {
105114
}
106115

107116
return {
108-
hasConsent: hasStatisticsConsent,
117+
hasConsent: hasMarketingConsent,
109118
init: initializeReoDev,
110119
};
111120
}

0 commit comments

Comments
 (0)