Skip to content

Commit

Permalink
feat: enable analytics w gdpr consent
Browse files Browse the repository at this point in the history
  • Loading branch information
ogous committed Sep 27, 2024
1 parent d496f97 commit c958a4b
Show file tree
Hide file tree
Showing 6 changed files with 145 additions and 6 deletions.
1 change: 1 addition & 0 deletions web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
},
"dependencies": {
"@graphql-typed-document-node/core": "^3.2.0",
"@next/third-parties": "^14.2.13",
"@radix-ui/react-alert-dialog": "^1.1.1",
"@radix-ui/react-dialog": "^1.1.1",
"@radix-ui/react-dropdown-menu": "^2.1.1",
Expand Down
20 changes: 20 additions & 0 deletions web/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 4 additions & 3 deletions web/src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ import { FeatureFlagConfig } from "@/app/_layout/FeatureFlagConfig";
import PopulateQueryCache from "@/app/PopulateQueryCache";
import BottomBanner from "@/components/Banners/BottomBanner";
import ErrorReportingDialog from "@/components/ErrorReportingDialog";
import { useChainId } from "wagmi";
import wagmiConfig from "@/config/wagmi";
import { superpositionTestnet } from "@/config/chains";
import CookieBanner from "@/components/CookieBanner";
import GoogleAnalytics from "@/components/GoogleAnalytics";

const title = "Longtail";

Expand Down Expand Up @@ -52,7 +52,6 @@ export const metadata: Metadata = {
},
};

/* istanbul ignore next */
const inter = Inter({
subsets: ["latin"],
weight: ["400", "500"],
Expand Down Expand Up @@ -140,7 +139,9 @@ export default async function RootLayout({
<BottomBanner />
<ErrorReportingDialog />
</Provider>
<CookieBanner />
</body>
<GoogleAnalytics />
</html>
);
}
71 changes: 71 additions & 0 deletions web/src/components/CookieBanner.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
"use client";

import Link from "next/link";
import { useState, useEffect } from "react";
import { deniedConsent, grantedConsent } from "@/components/GoogleAnalytics";
import { Button } from "./ui/button";

function gtag(...args: any[]) {
window.dataLayer = window.dataLayer || [];
window.dataLayer.push(...args);
}

export default function CookieBanner() {
const [showConsentDialog, setShowConsentDialog] = useState(false);

function denyCookies() {
gtag("consent", "update", deniedConsent);
window.localStorage.setItem("consentMode", JSON.stringify(deniedConsent));
setShowConsentDialog(false);
}

function allowCookies() {
gtag("consent", "update", grantedConsent);
window.localStorage.setItem("consentMode", JSON.stringify(grantedConsent));
setShowConsentDialog(false);
}

useEffect(() => {
const consent = window.localStorage.getItem("consentMode");
if (!consent) {
setShowConsentDialog(true);
return;
}
const consentMode = JSON.parse(consent) as
| typeof grantedConsent
| typeof deniedConsent;
if (consentMode.ad_storage === "denied") {
setShowConsentDialog(true);
return;
}
}, []);

if (!showConsentDialog) return null;

return (
<div className="fixed inset-x-0 bottom-0 z-50 mx-auto mb-[72px] flex max-w-max flex-col items-center justify-between gap-4 rounded-lg bg-[#1E1E1E] p-3 shadow sm:flex-row md:mb-4 md:max-w-screen-sm md:px-4">
<div className="text-center text-white">
<Link target="_blank" href="https://static.long.so/privacy-policy.pdf">
<p>
We use <span className="font-bold">cookies</span> on our site.
</p>
</Link>
</div>

<div className="flex gap-2">
<button
className="rounded-md border-gray-900 px-5 py-2 text-gray-300"
onClick={denyCookies}
>
Decline
</button>
<button
className="rounded-lg bg-white px-5 py-2 text-black"
onClick={allowCookies}
>
Allow Cookies
</button>
</div>
</div>
);
}
46 changes: 46 additions & 0 deletions web/src/components/GoogleAnalytics.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
"use client";
import Script from "next/script";
import { GoogleTagManager } from "@next/third-parties/google";

export const grantedConsent = {
ad_storage: "granted",
analytics_storage: "granted",
functionality_storage: "granted",
personalization_storage: "granted",
security_storage: "granted",
} as const;

export const deniedConsent = {
ad_storage: "denied",
analytics_storage: "denied",
functionality_storage: "denied",
personalization_storage: "denied",
security_storage: "denied",
} as const;

export default function GoogleAnalytics() {
const gtmId = "GTM-M22BZ6KC";
return (
<>
<Script id="google-consent" strategy="afterInteractive">
{`
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
if (localStorage.getItem('consentMode') === null) {
gtag('consent', 'default', ${JSON.stringify(deniedConsent)});
} else {
gtag('consent', 'default', JSON.parse(localStorage.getItem('consentMode')));
}
if (localStorage.getItem('userId') != null) {
window.dataLayer.push({
'walletAddress': localStorage.getItem('walletAddress')
});
}
`}
</Script>
<GoogleTagManager gtmId={gtmId} />
</>
);
}
6 changes: 3 additions & 3 deletions web/src/context/contextInjector.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
"use client";

import { useAccount, useChainId } from "wagmi";
import { useAccount } from "wagmi";
import { useEffect } from "react";
import { setTag, setUser } from "@sentry/nextjs";
export default function ContextInjector() {
const account = useAccount();

useEffect(() => {
if (account?.address) {
// window.localStorage.setItem("walletAddress", account.address); // this one is going to be needed for GTM
window.localStorage.setItem("walletAddress", account.address);
setUser({ id: account.address });
} else {
// window.localStorage.removeItem("walletAddress");
window.localStorage.removeItem("walletAddress");
setUser(null);
}
}, [account?.address]);
Expand Down

0 comments on commit c958a4b

Please sign in to comment.