From 0b537348a68f544e80e8f6f26713c2e4f88a8ddf Mon Sep 17 00:00:00 2001 From: Rishabh Singh Date: Fri, 4 Sep 2026 13:59:05 +0530 Subject: [PATCH] chore: install GTM tag manager, split dev/prod containers new.admin.opencerts.io and newadmin.dev.opencerts.io previously served no tag at all. This is a static SPA with no server-side template hook, so src/gtm.ts injects the GTM script/noscript tags programmatically from main.tsx, gated on VITE_GTM_CONTAINER_ID being set. Sourced from separate GTM_CONTAINER_ID / DEV_GTM_CONTAINER_ID repo secrets per environment, mapped to VITE_GTM_CONTAINER_ID in the build step (Vite requires the VITE_ prefix to expose an env var to client code). Co-Authored-By: Claude Sonnet 5 --- .env.example | 1 + .github/workflows/deploy-s3-dev.yml | 2 ++ .github/workflows/deploy-s3-prod.yml | 2 ++ src/gtm.ts | 32 ++++++++++++++++++++++++++++ src/main.tsx | 3 +++ src/vite-env.d.ts | 5 +++++ 6 files changed, 45 insertions(+) create mode 100644 .env.example create mode 100644 src/gtm.ts create mode 100644 src/vite-env.d.ts diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..14e7f6a --- /dev/null +++ b/.env.example @@ -0,0 +1 @@ +VITE_GTM_CONTAINER_ID=GTM-XXXXXXX diff --git a/.github/workflows/deploy-s3-dev.yml b/.github/workflows/deploy-s3-dev.yml index 100c033..dbb41a4 100644 --- a/.github/workflows/deploy-s3-dev.yml +++ b/.github/workflows/deploy-s3-dev.yml @@ -42,6 +42,8 @@ jobs: - name: Build run: npm run build + env: + VITE_GTM_CONTAINER_ID: ${{ secrets.DEV_GTM_CONTAINER_ID }} - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v4 diff --git a/.github/workflows/deploy-s3-prod.yml b/.github/workflows/deploy-s3-prod.yml index 67db4d2..653050b 100644 --- a/.github/workflows/deploy-s3-prod.yml +++ b/.github/workflows/deploy-s3-prod.yml @@ -41,6 +41,8 @@ jobs: - name: Build run: npm run build + env: + VITE_GTM_CONTAINER_ID: ${{ secrets.GTM_CONTAINER_ID }} - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v4 diff --git a/src/gtm.ts b/src/gtm.ts new file mode 100644 index 0000000..589c613 --- /dev/null +++ b/src/gtm.ts @@ -0,0 +1,32 @@ +interface GTMEvent { + event: string; + [key: string]: unknown; +} + +declare global { + interface Window { + dataLayer: GTMEvent[]; + } +} + +export const initGTM = (containerId?: string): void => { + if (!containerId) return; + + window.dataLayer = window.dataLayer ?? []; + window.dataLayer.push({ "gtm.start": new Date().getTime(), event: "gtm.js" }); + + const script = document.createElement("script"); + script.async = true; + script.src = `https://www.googletagmanager.com/gtm.js?id=${containerId}`; + document.head.insertBefore(script, document.head.firstChild); + + const iframe = document.createElement("iframe"); + iframe.src = `https://www.googletagmanager.com/ns.html?id=${containerId}`; + iframe.height = "0"; + iframe.width = "0"; + iframe.style.display = "none"; + iframe.style.visibility = "hidden"; + const noscript = document.createElement("noscript"); + noscript.appendChild(iframe); + document.body.insertBefore(noscript, document.body.firstChild); +}; diff --git a/src/main.tsx b/src/main.tsx index dddcbe4..46b94c8 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -3,6 +3,9 @@ import ReactDOM from "react-dom"; import "./index.css"; import "shepherd.js/dist/css/shepherd.css"; import App from "./app"; +import { initGTM } from "./gtm"; + +initGTM(import.meta.env.VITE_GTM_CONTAINER_ID); ReactDOM.render( diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts new file mode 100644 index 0000000..fca12b8 --- /dev/null +++ b/src/vite-env.d.ts @@ -0,0 +1,5 @@ +/// + +interface ImportMetaEnv { + readonly VITE_GTM_CONTAINER_ID?: string; +}