feat: gtm
This commit is contained in:
parent
5f2f5581b2
commit
630602858e
6 changed files with 89 additions and 0 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -58,3 +58,6 @@ Thumbs.db
|
|||
.secrets/
|
||||
libraries/plugins/src/plugins.ts
|
||||
i18n.cache
|
||||
|
||||
# Generated by apps/frontend/scripts/fetch-gtm.mjs on install
|
||||
apps/frontend/public/g.js
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@
|
|||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "dotenv -e ../../.env -- next dev -p 4200",
|
||||
"fetch-gtm": "node scripts/fetch-gtm.mjs",
|
||||
"postinstall": "node scripts/fetch-gtm.mjs",
|
||||
"build": "next build",
|
||||
"build:sentry": "dotenv -e ../../.env -- next build",
|
||||
"start": "dotenv -e ../../.env -- next start -p 4200",
|
||||
|
|
|
|||
50
apps/frontend/scripts/fetch-gtm.mjs
Normal file
50
apps/frontend/scripts/fetch-gtm.mjs
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
import { writeFile, mkdir, readFile } from 'node:fs/promises';
|
||||
import { existsSync } from 'node:fs';
|
||||
import { dirname, resolve } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
const envPath = resolve(__dirname, '..', '..', '..', '.env');
|
||||
const outPath = resolve(__dirname, '..', 'public', 'g.js');
|
||||
|
||||
if (!process.env.NEXT_PUBLIC_GTM_ID && existsSync(envPath)) {
|
||||
const content = await readFile(envPath, 'utf8');
|
||||
for (const raw of content.split('\n')) {
|
||||
const line = raw.trim();
|
||||
if (!line || line.startsWith('#')) continue;
|
||||
const eq = line.indexOf('=');
|
||||
if (eq === -1) continue;
|
||||
const key = line.slice(0, eq).trim();
|
||||
let value = line.slice(eq + 1).trim();
|
||||
if (
|
||||
(value.startsWith('"') && value.endsWith('"')) ||
|
||||
(value.startsWith("'") && value.endsWith("'"))
|
||||
) {
|
||||
value = value.slice(1, -1);
|
||||
}
|
||||
if (!process.env[key]) process.env[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
const id = process.env.NEXT_PUBLIC_GTM_ID;
|
||||
if (!id) {
|
||||
console.log('[fetch-gtm] NEXT_PUBLIC_GTM_ID not set, skipping');
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
const url = `https://www.googletagmanager.com/gtm.js?id=${encodeURIComponent(id)}`;
|
||||
try {
|
||||
console.log(`[fetch-gtm] fetching ${url}`);
|
||||
const res = await fetch(url);
|
||||
if (!res.ok) {
|
||||
console.warn(`[fetch-gtm] non-OK response ${res.status}, skipping`);
|
||||
process.exit(0);
|
||||
}
|
||||
const body = await res.text();
|
||||
await mkdir(dirname(outPath), { recursive: true });
|
||||
await writeFile(outPath, body, 'utf8');
|
||||
console.log(`[fetch-gtm] wrote ${outPath} (${body.length} bytes)`);
|
||||
} catch (err) {
|
||||
console.warn(`[fetch-gtm] failed: ${err?.message || err}, skipping`);
|
||||
process.exit(0);
|
||||
}
|
||||
|
|
@ -15,6 +15,7 @@ import { PHProvider } from '@gitroom/react/helpers/posthog';
|
|||
import UtmSaver from '@gitroom/helpers/utils/utm.saver';
|
||||
import { DubAnalytics } from '@gitroom/frontend/components/layout/dubAnalytics';
|
||||
import { FacebookComponent } from '@gitroom/frontend/components/layout/facebook.component';
|
||||
import { GoogleTagManagerComponent } from '@gitroom/frontend/components/layout/gtm.component';
|
||||
import { cookies } from 'next/headers';
|
||||
import {
|
||||
cookieName,
|
||||
|
|
@ -96,6 +97,7 @@ export default async function AppLayout({ children }: { children: ReactNode }) {
|
|||
<HtmlComponent />
|
||||
<DubAnalytics />
|
||||
<FacebookComponent />
|
||||
<GoogleTagManagerComponent gtmId={process.env.NEXT_PUBLIC_GTM_ID} />
|
||||
<Plausible
|
||||
domain={!!process.env.IS_GENERAL ? 'postiz.com' : 'gitroom.com'}
|
||||
>
|
||||
|
|
|
|||
21
apps/frontend/src/components/layout/gtm.component.tsx
Normal file
21
apps/frontend/src/components/layout/gtm.component.tsx
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
'use client';
|
||||
|
||||
import Script from 'next/script';
|
||||
import { FC } from 'react';
|
||||
|
||||
export const GoogleTagManagerComponent: FC<{ gtmId?: string }> = ({
|
||||
gtmId,
|
||||
}) => {
|
||||
if (!gtmId) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<Script strategy="afterInteractive" id="gtm">
|
||||
{`(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
|
||||
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
|
||||
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
|
||||
'/g.js?id='+i+dl;f.parentNode.insertBefore(j,f);
|
||||
})(window,document,'script','dataLayer','${gtmId}');`}
|
||||
</Script>
|
||||
);
|
||||
};
|
||||
|
|
@ -27,6 +27,17 @@ export const Onboarding: FC = () => {
|
|||
}
|
||||
return;
|
||||
}
|
||||
if (typeof window !== 'undefined') {
|
||||
const check = query.get('check') || 'unknown';
|
||||
const key = `gtm_start_trial_${check}`;
|
||||
if (!sessionStorage.getItem(key)) {
|
||||
sessionStorage.setItem(key, '1');
|
||||
// @ts-ignore
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
// @ts-ignore
|
||||
window.dataLayer.push({ event: 'start_trial', check });
|
||||
}
|
||||
}
|
||||
if (modalOpen.current) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue