TypeScript reactive library for Google Tag Manager with configurable priority system, RxJS, and automatic duplicate prevention in Frontend and SSR environments.
- Configurable priorities: 1 = critical, 2 = high, 3+ = low
- Multiple events per priority: FIFO within each level
- Immediate processing for priority 1
- Debounce & batching customizable per event
npm install gtm-coreOptional for schema validation with Zod:
npm install zodtu-project/
├── lib/
│ └── gtm.ts ← Central GTM configuration
├── hooks/
│ └── useGTM.ts ← Optional custom hook
├── context/
│ └── GTMContext.tsx ← Optional React context
├── pages/ or src/
│ ├── App.tsx ← Global initialization
│ ├── HomePage.tsx ← Example view
│ └── ProductPage.tsx ← Another example view
└── package.json
import { PriorityGTMManager, EventPriorityConfig } from 'gtm-core';
interface AppEvents {
criticalError: { error: string }; // P1 – Critical
userClick: { element: string; page: string }; // P2 – Important
pageView: { page: string; title: string }; // P3 – General
scrollDepth: { page: string; depth: number }; // P3 – General
}
const events: EventPriorityConfig<AppEvents> = {
criticalError: { priority: 1, debounceMs: 0 },
userClick: { priority: 2, debounceMs: 100, maxPerBatch: 5 },
pageView: { priority: 3, debounceMs: 300, maxPerBatch: 3 },
scrollDepth: { priority: 3, debounceMs: 1000, maxPerBatch: 2 }
};
export const gtm = new PriorityGTMManager<AppEvents>({
gtm: { gtmId: 'GTM-XXXXXXX' }, // ← Your GTM ID
events,
batcher: { batchSize: 8, batchIntervalMs: 1500, priorityAware: true },
reactMode: { enabled: true, globalDebounceMs: 50 }
});import React, { useEffect } from 'react';
import { gtm } from './lib/gtm';
function App({ Component, pageProps }) {
useEffect(() => {
gtm.init().subscribe({
next: () => console.log('✅ GTM initialized'),
error: (e) => console.error('❌ GTM init error:', e)
});
}, []);
return <Component {...pageProps} />;
}
export default App;useEffect(() => {
gtm.pushSync({ page: '/home', title: 'Home' }, 'pageView');
}, []);<button onClick={() =>
gtm.pushSync({ element: 'cta', page: '/home' }, 'userClick')
}>
Click me
</button>try {
await processPayment();
} catch (error) {
gtm.pushSync({ error: error.message }, 'criticalError');
}- P1 (
priority: 1):debounceMs: 0→ immediate - P2 (
priority: 2):debounceMs: 100ms → short burst grouping - P3 (
priority: 3):debounceMs: 300ms → longer grouping
Batcher groups up to batchSize events or every batchIntervalMs, respecting priorities if priorityAware: true.
import Document, { Html, Head, Main, NextScript } from 'next/document';
import { gtm } from '../lib/gtm';
class MyDocument extends Document {
render() {
const script = gtm.renderSSRScriptSync();
return (
<Html>
<Head>{script && <div dangerouslySetInnerHTML={{ __html: script }} />}</Head>
<body><Main /><NextScript/></body>
</Html>
);
}
}
export default MyDocument;import { useCallback } from 'react';
import { gtm } from '../lib/gtm';
export function useGTM() {
const push = useCallback((data, type) => gtm.pushSync(data, type), []);
const trackPage = useCallback((page, title) => push({ page, title }, 'pageView'), [push]);
const trackClick = useCallback((el, pg) => push({ element: el, page: pg }, 'userClick'), [push]);
return { push, trackPage, trackClick };
}import React, { createContext, useContext } from 'react';
import { gtm } from '../lib/gtm';
const GTMContext = createContext(gtm);
export const GTMProvider = ({ children }) => (
<GTMContext.Provider value={gtm}>{children}</GTMContext.Provider>
);
export const useGTM = () => useContext(GTMContext);Wrap your app in GTMProvider if using.
// Discarded events
gtm.buffer.getDiscardedEvents().subscribe(({ reason, event }) => {
console.warn('Discarded:', reason, event);
});
// Processed batches
gtm.batcher.getBatchEvents().subscribe(be => {
console.log(`Batch ${be.reason} (P=${be.avgPriority?.toFixed(1)}):`, be.batch);
});- Install:
npm install gtm-core - Configure: Define your
AppEventsandEventPriorityConfig - Initialize: Call
gtm.init()in your root component - Send: Use
gtm.pushSync(data, 'eventType')in each view - Adjust: Tune
debounceMs,maxPerBatch,batcher,reactMode
GTM Core - v1.0.0 handles your critical, important, and general events automatically, both on client and SSR. 🎉