From f2e985cfeadb46b70548f5b8da45af51a8892639 Mon Sep 17 00:00:00 2001
From: Eugene Fox
Date: Thu, 24 Oct 2024 16:20:34 +0000
Subject: [PATCH] fix: cookie consent tracking breaks when CDN caching is
involved
---
app/_components/CookieBanner.tsx | 5 ++++-
app/_utils/analytics/server.ts | 10 +---------
app/attribution/page.tsx | 18 ++++++++++++------
app/layout.tsx | 10 ++++++----
public/clarity.js | 3 ++-
5 files changed, 25 insertions(+), 21 deletions(-)
diff --git a/app/_components/CookieBanner.tsx b/app/_components/CookieBanner.tsx
index 5743828..10a7582 100644
--- a/app/_components/CookieBanner.tsx
+++ b/app/_components/CookieBanner.tsx
@@ -12,11 +12,14 @@ const CookieBanner: React.FC<{ askForConsent: boolean; }> = props =>
useEffect(() =>
{
+ if (navigator.doNotTrack === "1")
+ return;
+
const choice = getCookieChoice();
setVisible(choice === "none");
// Since Clarity cookies expiration dates extend well beyond 60 days,
- // we need to terminate them manually once our consent tracking cookie expires.
+ // we need to terminate them manually once our consent tracking cookie expired.
if (choice !== "accepted")
window.clarity?.("consent", false);
}, []);
diff --git a/app/_utils/analytics/server.ts b/app/_utils/analytics/server.ts
index b781d7e..ec79db2 100644
--- a/app/_utils/analytics/server.ts
+++ b/app/_utils/analytics/server.ts
@@ -1,5 +1,4 @@
import { unstable_noStore } from "next/cache";
-import { headers } from "next/headers";
/**
* Check if Clarity is enabled
@@ -15,15 +14,8 @@ export const analyticsEnabled = (): boolean =>
* Check if Clarity requires explicit consent
* @returns true if Clarity requires explicit consent
*/
-export const requireExcplicitConsent = (): boolean =>
+export const requireExplicitConsent = (): boolean =>
{
unstable_noStore();
return process.env.CLARITY_CONSENT === "1";
};
-
-/**
- * Check if Clarity is enabled and the browser didn't send a DNT signal
- * @returns true if Clarity is enabled and the browser didn't send a DNT signal
- */
-export const canLoadAnalytics = (): boolean =>
- analyticsEnabled() && headers().get("Dnt") !== "1";
diff --git a/app/attribution/page.tsx b/app/attribution/page.tsx
index 42467d3..f3c35ac 100644
--- a/app/attribution/page.tsx
+++ b/app/attribution/page.tsx
@@ -3,7 +3,7 @@ import Button from "@/_components/Button";
import RevokeConsentButton from "@/_components/RevokeConsentButton";
import { canonicalName, getTitle } from "@/_data/metadata";
import ThirdPartyAttribution from "@/_data/ThirdPartyAttributiont";
-import { analyticsEnabled } from "@/_utils/analytics/server";
+import { analyticsEnabled, requireExplicitConsent } from "@/_utils/analytics/server";
import { ArrowLeft24Regular, ArrowRight24Regular } from "@fluentui/react-icons";
import { Metadata } from "next";
import { unstable_noStore } from "next/cache";
@@ -42,14 +42,20 @@ const AttributionPage: React.FC = () => (
see the Microsoft Privacy Statement.
- If the "Do Not Track" option is enabled in your browser, the website will not load any tracking code.
-
-
- If you previously gave your consent to use cookies, you can revoke it by clicking "Revoke my consent" button on this page below (the button is available only if the consent was given). Recorded data will be deleted after 30-day retention period.
+ If the "Do Not Track" option is enabled in your browser,
+ the website will not execute any tracking code.
+ { requireExplicitConsent() &&
+
+ If you previously gave your consent to use cookies,
+ you can revoke it by clicking "Revoke my consent" button on this page below
+ (the button is available only if the consent was given).
+ Recorded data will be deleted after 30-day retention period.
+
+ }
-
+ { requireExplicitConsent() && }
}>
diff --git a/app/layout.tsx b/app/layout.tsx
index 7dc1a17..3240359 100644
--- a/app/layout.tsx
+++ b/app/layout.tsx
@@ -5,7 +5,7 @@ import { PropsWithChildren } from "react";
import CookieBanner from "./_components/CookieBanner";
import Footer from "./_components/Footer";
import Header from "./_components/Header";
-import { canLoadAnalytics, requireExcplicitConsent } from "./_utils/analytics/server";
+import { analyticsEnabled, requireExplicitConsent } from "./_utils/analytics/server";
import fonts from "./fonts";
import "./globals.scss";
@@ -23,12 +23,14 @@ export default function RootLayout(props: PropsWithChildren)
{
return (
i.variable).join(" ") }>
- { canLoadAnalytics() &&
- // If "Do Not Track" is enabled, or there's no CLARITY_ID set up, we don't load any analytics
+ { analyticsEnabled() &&
}
- { canLoadAnalytics() && }
+ { analyticsEnabled() &&
+
+ }
+
{ props.children }
diff --git a/public/clarity.js b/public/clarity.js
index 3136fd1..a569af9 100644
--- a/public/clarity.js
+++ b/public/clarity.js
@@ -30,7 +30,8 @@
/** @type {string | undefined} */
const id = document.getElementById("ms-clarity")?.dataset.id;
- if (!id)
+ // If "Do Not Track" is enabled, or there's no CLARITY_ID set up, we don't load any analytics
+ if (!id || navigator.doNotTrack === "1")
return;
window["clarity"] ??= function ()