@jwiedeman/gtm-kit
v1.2.2
Published
Framework-agnostic Google Tag Manager client - the core of GTM Kit. Zero dependencies, 3.7KB gzipped.
Maintainers
Readme
@jwiedeman/gtm-kit
Framework-agnostic Google Tag Manager client. Zero dependencies. 3.7KB gzipped.
The foundation of GTM Kit - works with any JavaScript project, framework, or build system.
Installation
npm install @jwiedeman/gtm-kityarn add @jwiedeman/gtm-kitpnpm add @jwiedeman/gtm-kitQuick Start
import { createGtmClient, pushEvent } from '@jwiedeman/gtm-kit';
// Create and initialize
const gtm = createGtmClient({ containers: 'GTM-XXXXXX' });
gtm.init();
// Push events
pushEvent(gtm, 'page_view', { page_path: '/' });
pushEvent(gtm, 'purchase', { value: 49.99, currency: 'USD' });Features
| Feature | Description | | ----------------------- | ------------------------------------- | | Zero Dependencies | No bloat - just what you need | | 3.7KB Gzipped | Minimal impact on bundle size | | Auto-Queue | Automatic buffering eliminates races | | SSR-Safe | Works with server-side rendering | | Consent Mode v2 | Built-in GDPR compliance support | | Multiple Containers | Load multiple GTM containers | | Custom DataLayer | Use custom dataLayer names | | CSP Support | Content Security Policy nonce support | | TypeScript | Full type definitions included |
API Reference
createGtmClient(config)
Creates a new GTM client instance.
const client = createGtmClient({
containers: 'GTM-XXXXXX', // Required: ID or array of IDs
dataLayerName: 'dataLayer', // Optional: custom name
host: 'https://www.googletagmanager.com', // Optional: custom host
scriptAttributes: { nonce: '...' } // Optional: for CSP
});Client Methods
client.init(); // Load GTM scripts
client.push({ event: 'custom' }); // Push to dataLayer
client.setConsentDefaults(state); // Set consent (before init)
client.updateConsent(state); // Update consent (after action)
client.teardown(); // Cleanup (for tests)
await client.whenReady(); // Wait for scripts to loadEvent Helpers
import { pushEvent, pushEcommerce } from '@jwiedeman/gtm-kit';
// Generic event
pushEvent(client, 'button_click', { button_id: 'cta-main' });
// Ecommerce event (GA4 format)
pushEcommerce(client, 'purchase', {
transaction_id: 'T-12345',
value: 120.0,
currency: 'USD',
items: [{ item_id: 'SKU-001', item_name: 'Blue T-Shirt', price: 40, quantity: 3 }]
});Consent Mode v2
import { consentPresets } from '@jwiedeman/gtm-kit';
// Set defaults BEFORE init (required by Google)
client.setConsentDefaults(consentPresets.eeaDefault, { region: ['EEA'] });
client.init();
// Update after user consent
client.updateConsent({
ad_storage: 'granted',
analytics_storage: 'granted',
ad_user_data: 'granted',
ad_personalization: 'granted'
});Granular Consent - Update individual categories without affecting others:
// All granted
client.updateConsent(consentPresets.allGranted);
// All denied
client.updateConsent(consentPresets.eeaDefault);
// Mixed: analytics only, no ads
client.updateConsent(consentPresets.analyticsOnly);
// Partial update: only update specific categories
client.updateConsent({ analytics_storage: 'granted' });
// Update multiple specific categories
client.updateConsent({ ad_storage: 'granted', ad_user_data: 'granted' });Built-in Presets:
| Preset | ad_storage | analytics_storage | ad_user_data | ad_personalization |
| --------------- | ---------- | ----------------- | ------------ | ------------------ |
| eeaDefault | denied | denied | denied | denied |
| allGranted | granted | granted | granted | granted |
| analyticsOnly | denied | granted | denied | denied |
Multiple Containers
const client = createGtmClient({
containers: [{ id: 'GTM-MAIN' }, { id: 'GTM-ADS', queryParams: { gtm_auth: 'abc', gtm_preview: 'env-1' } }]
});SSR / Server-Side Rendering
import { createNoscriptMarkup } from '@jwiedeman/gtm-kit';
// Generate noscript HTML for server-side rendering
const noscriptHtml = createNoscriptMarkup('GTM-XXXXXX');
// Returns: '<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-XXXXXX" ...></iframe></noscript>'Auto-Queue (Race Condition Protection)
Automatically buffer events that fire before GTM loads, then replay them in order:
import { installAutoQueue, createGtmClient } from '@jwiedeman/gtm-kit';
// Install FIRST - captures all dataLayer pushes
installAutoQueue();
// Events before GTM loads are buffered
window.dataLayer.push({ event: 'early_event' }); // Buffered!
// When GTM loads, everything replays automatically
const client = createGtmClient({ containers: 'GTM-XXXXXX' });
client.init(); // Buffer replays, GTM processes all eventsFor earliest possible protection, embed in your HTML <head>:
import { createAutoQueueScript } from '@jwiedeman/gtm-kit';
// Returns minified inline script for SSR
const script = createAutoQueueScript();
// Output: <script>{script}</script> in <head>Configuration:
installAutoQueue({
pollInterval: 50, // Check interval (ms)
timeout: 30000, // Max wait time (ms)
maxBufferSize: 1000, // Prevent memory issues
onReplay: (count) => console.log(`Replayed ${count} events`),
onTimeout: (count) => console.warn(`GTM slow, ${count} waiting`)
});Framework Adapters
While @jwiedeman/gtm-kit works standalone, we provide framework-specific adapters for better ergonomics:
| Framework | Package | Install |
| ------------- | --------------------------------- | ---------------------------------------------------------------- |
| React (hooks) | @jwiedeman/gtm-kit-react | npm install @jwiedeman/gtm-kit @jwiedeman/gtm-kit-react |
| React (class) | @jwiedeman/gtm-kit-react-legacy | npm install @jwiedeman/gtm-kit @jwiedeman/gtm-kit-react-legacy |
| Vue 3 | @jwiedeman/gtm-kit-vue | npm install @jwiedeman/gtm-kit @jwiedeman/gtm-kit-vue |
| Nuxt 3 | @jwiedeman/gtm-kit-nuxt | npm install @jwiedeman/gtm-kit @jwiedeman/gtm-kit-nuxt |
| Next.js | @jwiedeman/gtm-kit-next | npm install @jwiedeman/gtm-kit @jwiedeman/gtm-kit-next |
| Svelte | @jwiedeman/gtm-kit-svelte | npm install @jwiedeman/gtm-kit @jwiedeman/gtm-kit-svelte |
| SolidJS | @jwiedeman/gtm-kit-solid | npm install @jwiedeman/gtm-kit @jwiedeman/gtm-kit-solid |
| Remix | @jwiedeman/gtm-kit-remix | npm install @jwiedeman/gtm-kit @jwiedeman/gtm-kit-remix |
| Astro | @jwiedeman/gtm-kit-astro | npm install @jwiedeman/gtm-kit @jwiedeman/gtm-kit-astro |
Related Packages
| Framework | Package | | --------- | ------------------------------------------------------------------------------------ | | React | @jwiedeman/gtm-kit-react | | Vue 3 | @jwiedeman/gtm-kit-vue | | Next.js | @jwiedeman/gtm-kit-next | | Nuxt 3 | @jwiedeman/gtm-kit-nuxt | | Svelte | @jwiedeman/gtm-kit-svelte | | SolidJS | @jwiedeman/gtm-kit-solid | | Remix | @jwiedeman/gtm-kit-remix | | Astro | @jwiedeman/gtm-kit-astro | | CLI | @jwiedeman/gtm-kit-cli |
Support
Have a question, found a bug, or need help?
Open an issue on GitHub — we're actively maintaining this project and respond quickly.
License
MIT
