diff --git a/.env.example b/.env.example
new file mode 100644
index 0000000..7867ade
--- /dev/null
+++ b/.env.example
@@ -0,0 +1,4 @@
+VITE_GA_ID=G-XXXXXXXXXX
+
+# Add your Google Analytics Measurement ID above.
+# Example: VITE_GA_ID=G-1A2B3C4D5E
diff --git a/src/App.tsx b/src/App.tsx
index c0a2710..fb6c0aa 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -3,17 +3,21 @@ import Index from "./pages/Index";
import Privacy from "./pages/Privacy";
import NotFound from "./pages/NotFound";
import Waitlist from "./pages/Waitlist";
+import CookieConsent from "./components/ui/CookieConsent";
const App = () => (
-
-
- } />
- } />
- } />
- {/* ADD ALL CUSTOM ROUTES ABOVE THE CATCH-ALL "*" ROUTE */}
- } />
-
-
+ <>
+
+
+ } />
+ } />
+ } />
+ {/* ADD ALL CUSTOM ROUTES ABOVE THE CATCH-ALL "*" ROUTE */}
+ } />
+
+
+
+ >
);
export default App;
diff --git a/src/components/landing/Footer.tsx b/src/components/landing/Footer.tsx
index d77e7b6..68c8d5f 100644
--- a/src/components/landing/Footer.tsx
+++ b/src/components/landing/Footer.tsx
@@ -24,6 +24,8 @@ const Footer = () => {
diff --git a/src/components/ui/CookieConsent.tsx b/src/components/ui/CookieConsent.tsx
new file mode 100644
index 0000000..510ff6b
--- /dev/null
+++ b/src/components/ui/CookieConsent.tsx
@@ -0,0 +1,84 @@
+import React, { useEffect, useState } from "react";
+
+declare global {
+ interface Window {
+ dataLayer?: any[];
+ gtag?: (...args: any[]) => void;
+ }
+}
+
+const STORAGE_KEY = "tt_cookie_consent";
+
+function loadGtag(id: string) {
+ if (!id) return;
+ if (document.querySelector(`script[data-gtag="${id}"]`)) return;
+
+ const script = document.createElement("script");
+ script.async = true;
+ script.src = `https://www.googletagmanager.com/gtag/js?id=${id}`;
+ script.setAttribute("data-gtag", id);
+ document.head.appendChild(script);
+
+ window.dataLayer = window.dataLayer || [];
+ window.gtag = function () {
+ // @ts-ignore - forward arguments to the dataLayer
+ window.dataLayer!.push(arguments);
+ };
+
+ window.gtag("js", new Date());
+ window.gtag("config", id, { anonymize_ip: true });
+}
+
+const CookieConsent: React.FC = () => {
+ const [consent, setConsent] = useState
(null);
+
+ useEffect(() => {
+ const v = localStorage.getItem(STORAGE_KEY);
+ setConsent(v);
+ if (v === "granted") {
+ const id = (import.meta.env as any).VITE_GA_ID as string | undefined;
+ if (id) loadGtag(id);
+ }
+ }, []);
+
+ function accept() {
+ localStorage.setItem(STORAGE_KEY, "granted");
+ setConsent("granted");
+ const id = (import.meta.env as any).VITE_GA_ID as string | undefined;
+ if (id) loadGtag(id);
+ }
+
+ function deny() {
+ localStorage.setItem(STORAGE_KEY, "denied");
+ setConsent("denied");
+ }
+
+ if (consent !== null) return null;
+
+ return (
+
+
+
+ We use cookies for analytics.
+
+
+
+
+
+
+
+
+ );
+};
+
+export default CookieConsent;