@jwiedeman/gtm-kit-svelte
v1.2.0
Published
Svelte stores and actions for GTM Kit - Google Tag Manager integration with SvelteKit SSR support.
Maintainers
Readme
@jwiedeman/gtm-kit-svelte
Svelte stores and context for Google Tag Manager. Reactive by design.
The Svelte adapter for GTM Kit - provides stores and context for idiomatic Svelte integration.
Installation
npm install @jwiedeman/gtm-kit @jwiedeman/gtm-kit-svelteyarn add @jwiedeman/gtm-kit @jwiedeman/gtm-kit-sveltepnpm add @jwiedeman/gtm-kit @jwiedeman/gtm-kit-svelteQuick Start
Step 1: Create Store in Layout
<!-- src/routes/+layout.svelte -->
<script>
import { createGtmStore, setGtmContext } from '@jwiedeman/gtm-kit-svelte';
const gtm = createGtmStore({ containers: 'GTM-XXXXXX' });
setGtmContext(gtm);
</script>
<slot />Step 2: Push Events
<!-- src/routes/+page.svelte -->
<script>
import { getGtmContext } from '@jwiedeman/gtm-kit-svelte';
const gtm = getGtmContext();
function handleClick() {
$gtm.push({ event: 'purchase', value: 49.99 });
}
</script>
<button on:click={handleClick}>Buy Now</button>That's it! GTM is now running.
Features
| Feature | Description |
| ------------------- | ------------------------------- |
| Svelte Stores | Native Svelte store integration |
| Context API | Uses Svelte context for DI |
| Reactive | Fully reactive with $ syntax |
| TypeScript | Full type definitions included |
| Consent Mode v2 | Built-in GDPR compliance |
| SSR Compatible | Safe for SvelteKit SSR |
Available Functions
createGtmStore(options)
Creates a new GTM store. Call this once in your root layout.
<script>
import { createGtmStore, setGtmContext } from '@jwiedeman/gtm-kit-svelte';
const gtm = createGtmStore({
containers: 'GTM-XXXXXX',
autoInit: true, // default
onBeforeInit: (client) => {
// Set consent defaults here
}
});
setGtmContext(gtm);
</script>getGtmContext()
Gets the GTM store from context. Use in child components.
<script>
import { getGtmContext } from '@jwiedeman/gtm-kit-svelte';
const gtm = getGtmContext();
// Access store values reactively
$: ({ push, client, updateConsent } = $gtm);
</script>gtmPush()
Get a derived store for just the push function.
<script>
import { gtmPush } from '@jwiedeman/gtm-kit-svelte';
const push = gtmPush();
function track() {
$push({ event: 'button_click' });
}
</script>gtmConsent()
Get a derived store for consent functions.
<script>
import { gtmConsent } from '@jwiedeman/gtm-kit-svelte';
const consent = gtmConsent();
function acceptAll() {
$consent.updateConsent({
ad_storage: 'granted',
analytics_storage: 'granted'
});
}
</script>gtmClient()
Get a derived store for the raw GTM client.
<script>
import { gtmClient } from '@jwiedeman/gtm-kit-svelte';
const client = gtmClient();
</script>gtmReady()
Get a derived store for the whenReady function.
<script>
import { gtmReady } from '@jwiedeman/gtm-kit-svelte';
import { onMount } from 'svelte';
const whenReady = gtmReady();
onMount(async () => {
await $whenReady();
console.log('GTM is ready!');
});
</script>SvelteKit Integration
Basic Setup
<!-- src/routes/+layout.svelte -->
<script>
import { createGtmStore, setGtmContext } from '@jwiedeman/gtm-kit-svelte';
import { browser } from '$app/environment';
// Only create store in browser
if (browser) {
const gtm = createGtmStore({ containers: 'GTM-XXXXXX' });
setGtmContext(gtm);
}
</script>
<slot />Page Tracking
<!-- src/routes/+layout.svelte -->
<script>
import { createGtmStore, setGtmContext } from '@jwiedeman/gtm-kit-svelte';
import { page } from '$app/stores';
import { browser } from '$app/environment';
let gtm;
if (browser) {
gtm = createGtmStore({ containers: 'GTM-XXXXXX' });
setGtmContext(gtm);
// Track page views
$: if ($gtm && $page) {
$gtm.push({
event: 'page_view',
page_path: $page.url.pathname
});
}
}
</script>
<slot />Consent Mode v2 (GDPR)
<!-- src/routes/+layout.svelte -->
<script>
import { createGtmStore, setGtmContext } from '@jwiedeman/gtm-kit-svelte';
import { consentPresets } from '@jwiedeman/gtm-kit';
import { browser } from '$app/environment';
if (browser) {
const gtm = createGtmStore({
containers: 'GTM-XXXXXX',
onBeforeInit: (client) => {
// Deny by default for EU users
client.setConsentDefaults(consentPresets.eeaDefault, { region: ['EEA'] });
}
});
setGtmContext(gtm);
}
</script>
<slot /><!-- src/lib/CookieBanner.svelte -->
<script>
import { gtmConsent } from '@jwiedeman/gtm-kit-svelte';
const consent = gtmConsent();
function acceptAll() {
$consent.updateConsent({
ad_storage: 'granted',
analytics_storage: 'granted',
ad_user_data: 'granted',
ad_personalization: 'granted'
});
}
function rejectAll() {
$consent.updateConsent({
ad_storage: 'denied',
analytics_storage: 'denied',
ad_user_data: 'denied',
ad_personalization: 'denied'
});
}
</script>
<div class="cookie-banner">
<p>We use cookies to improve your experience.</p>
<button on:click={acceptAll}>Accept All</button>
<button on:click={rejectAll}>Reject All</button>
</div>Store Options
interface GtmStoreOptions {
// Required: GTM container ID(s)
containers: string | ContainerConfig | (string | ContainerConfig)[];
// Whether to auto-initialize GTM (default: true)
autoInit?: boolean;
// Custom dataLayer name (default: 'dataLayer')
dataLayerName?: string;
// Custom GTM host
host?: string;
// Script attributes (e.g., nonce for CSP)
scriptAttributes?: Record<string, string>;
// Called before GTM initializes
onBeforeInit?: (client: GtmClient) => void;
}TypeScript
Full TypeScript support is included:
<script lang="ts">
import { getGtmContext, type GtmStoreValue } from '@jwiedeman/gtm-kit-svelte';
import type { Writable } from 'svelte/store';
const gtm: Writable<GtmStoreValue> = getGtmContext();
</script>Requirements
- Svelte 4.0+ or 5.0+
@jwiedeman/gtm-kit(peer dependency)
Related Packages
- Core: @jwiedeman/gtm-kit (required)
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
