From df5c82dbab9e02d936d395dc1901d172567b59e0 Mon Sep 17 00:00:00 2001
From: Nurul Sundarani
Date: Thu, 18 Jun 2026 14:20:19 +0530
Subject: [PATCH 1/2] feat(analytics): add GA4 via Google Tag Manager across
site, blog, docs
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Load a single consent-gated GTM container (GTM-KRTRXXQ6, Prisma Main ›
prisma.io) across all three public zones, feeding the new GA4 property
(G-4B72WBX9ET). Replaces the legacy GTM-KCGZPWB container in the site app.
- Add shared loader in @prisma-docs/ui, reusing the
existing CookieYes consent-gating pattern (type="text/plain" +
data-cookieyes-category="analytics") so nothing loads before consent.
- Seed a `site_section` dataLayer value per zone (website/blog/docs) so GA4
reports unified totals and clean per-section breakdowns.
- Add trackCTA() helper and wire it into the blog CTA and ConsoleCtaButton
for structured `cta_click` events; a GTM auto-click trigger covers the rest.
GA4 config tag, cta_click event tag, and key-event setup are done in the
GTM/GA4 dashboards, not in code.
Co-Authored-By: Claude Opus 4.8
---
apps/blog/src/app/layout.tsx | 9 ++--
apps/blog/src/components/BlogCTA.tsx | 15 +++++-
apps/docs/src/app/layout.tsx | 12 ++---
apps/site/src/app/layout.tsx | 16 +------
.../src/components/console-cta-button.tsx | 18 ++++++-
.../ui/src/components/google-tag-manager.tsx | 47 +++++++++++++++++++
packages/ui/src/lib/analytics.ts | 39 +++++++++++++++
7 files changed, 128 insertions(+), 28 deletions(-)
create mode 100644 packages/ui/src/components/google-tag-manager.tsx
create mode 100644 packages/ui/src/lib/analytics.ts
diff --git a/apps/blog/src/app/layout.tsx b/apps/blog/src/app/layout.tsx
index 5bb1f91448..f59a6fa194 100644
--- a/apps/blog/src/app/layout.tsx
+++ b/apps/blog/src/app/layout.tsx
@@ -8,6 +8,7 @@ import Script from "next/script";
import { BLOG_HOME_DESCRIPTION, BLOG_HOME_TITLE } from "@/lib/blog-metadata";
import { FontAwesomeScript as EclipseFA } from "@prisma/eclipse";
import { JsonLd } from "@prisma-docs/ui/components/json-ld";
+import { GoogleTagManager } from "@prisma-docs/ui/components/google-tag-manager";
const inter = Inter({
subsets: ["latin"],
@@ -30,11 +31,7 @@ const blogStructuredData = createBlogStructuredData();
export default function Layout({ children }: LayoutProps<"/">) {
return (
-
+
{/* FontAwesome — not render-critical; explicit strategy prevents accidental beforeInteractive promotion */}
@@ -50,6 +47,8 @@ export default function Layout({ children }: LayoutProps<"/">) {
src="https://cdn-cookieyes.com/client_data/96980f76df67ad5235fc3f0d/script.js"
strategy="afterInteractive"
/>
+ {/* Google Tag Manager — consent-gated; activates only after CookieYes analytics consent */}
+
diff --git a/apps/blog/src/components/BlogCTA.tsx b/apps/blog/src/components/BlogCTA.tsx
index 0fa88f2ab9..2ea1c7ee14 100644
--- a/apps/blog/src/components/BlogCTA.tsx
+++ b/apps/blog/src/components/BlogCTA.tsx
@@ -1,4 +1,7 @@
+"use client";
+
import { Button } from "@prisma/eclipse";
+import { trackCTA } from "@prisma-docs/ui/lib/analytics";
const CTA_HREF = "https://pris.ly/pdp?utm_source=blog&utm_medium=blog_cta&utm_campaign=blog_post";
@@ -16,7 +19,17 @@ export const BlogCTA = () => {