@jwiedeman/gtm-kit-nuxt 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,313 @@
1
+ # @react-gtm-kit/nuxt
2
+
3
+ [![CI](https://github.com/jwiedeman/react-gtm-kit/actions/workflows/ci.yml/badge.svg)](https://github.com/jwiedeman/react-gtm-kit/actions/workflows/ci.yml)
4
+ [![Coverage](https://codecov.io/gh/jwiedeman/react-gtm-kit/graph/badge.svg?flag=nuxt)](https://codecov.io/gh/jwiedeman/react-gtm-kit)
5
+ [![npm version](https://img.shields.io/npm/v/@react-gtm-kit/nuxt.svg)](https://www.npmjs.com/package/@react-gtm-kit/nuxt)
6
+ [![Bundle Size](https://img.shields.io/bundlephobia/minzip/@react-gtm-kit/nuxt)](https://bundlephobia.com/package/@react-gtm-kit/nuxt)
7
+ [![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue.svg)](https://www.typescriptlang.org/)
8
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
9
+ [![Nuxt 3](https://img.shields.io/badge/Nuxt-3.0+-00DC82.svg?logo=nuxt.js)](https://nuxt.com/)
10
+
11
+ **Nuxt 3 module for Google Tag Manager. Auto page tracking. Zero config.**
12
+
13
+ The Nuxt adapter for GTM Kit - native module with automatic page tracking and SSR support.
14
+
15
+ ---
16
+
17
+ ## Installation
18
+
19
+ ```bash
20
+ npm install @react-gtm-kit/core @react-gtm-kit/nuxt
21
+ ```
22
+
23
+ ```bash
24
+ yarn add @react-gtm-kit/core @react-gtm-kit/nuxt
25
+ ```
26
+
27
+ ```bash
28
+ pnpm add @react-gtm-kit/core @react-gtm-kit/nuxt
29
+ ```
30
+
31
+ ---
32
+
33
+ ## Quick Start
34
+
35
+ ### Step 1: Create Plugin
36
+
37
+ ```ts
38
+ // plugins/gtm.client.ts
39
+ import { GtmPlugin } from '@react-gtm-kit/nuxt';
40
+
41
+ export default defineNuxtPlugin((nuxtApp) => {
42
+ nuxtApp.vueApp.use(GtmPlugin, { containers: 'GTM-XXXXXX' });
43
+ });
44
+ ```
45
+
46
+ ### Step 2: Push Events
47
+
48
+ ```vue
49
+ <script setup>
50
+ import { useGtm } from '@react-gtm-kit/vue';
51
+
52
+ const { push } = useGtm();
53
+
54
+ push({ event: 'page_view' });
55
+ </script>
56
+ ```
57
+
58
+ **That's it!** GTM is running with automatic page tracking.
59
+
60
+ ---
61
+
62
+ ## Features
63
+
64
+ | Feature | Description |
65
+ | ---------------------- | ----------------------------------- |
66
+ | **Native Nuxt Module** | Built specifically for Nuxt 3 |
67
+ | **Auto Page Tracking** | Tracks route changes automatically |
68
+ | **SSR Support** | Server-side rendering compatible |
69
+ | **Composables** | Uses Vue composables under the hood |
70
+ | **TypeScript** | Full type definitions included |
71
+ | **Consent Mode v2** | Built-in GDPR compliance |
72
+
73
+ ---
74
+
75
+ ## Plugin Configuration
76
+
77
+ ```ts
78
+ // plugins/gtm.client.ts
79
+ import { GtmPlugin } from '@react-gtm-kit/nuxt';
80
+ import { consentPresets } from '@react-gtm-kit/core';
81
+
82
+ export default defineNuxtPlugin((nuxtApp) => {
83
+ nuxtApp.vueApp.use(GtmPlugin, {
84
+ containers: 'GTM-XXXXXX',
85
+ dataLayerName: 'dataLayer',
86
+ onBeforeInit: (client) => {
87
+ // Set consent defaults for EU
88
+ client.setConsentDefaults(consentPresets.eeaDefault, { region: ['EEA'] });
89
+ }
90
+ });
91
+ });
92
+ ```
93
+
94
+ ---
95
+
96
+ ## Available Composables
97
+
98
+ All composables from `@react-gtm-kit/vue` are available:
99
+
100
+ ### `useGtm()`
101
+
102
+ ```vue
103
+ <script setup>
104
+ import { useGtm } from '@react-gtm-kit/vue';
105
+
106
+ const { push, updateConsent } = useGtm();
107
+ </script>
108
+ ```
109
+
110
+ ### `useGtmPush()`
111
+
112
+ ```vue
113
+ <script setup>
114
+ import { useGtmPush } from '@react-gtm-kit/vue';
115
+
116
+ const push = useGtmPush();
117
+
118
+ push({ event: 'purchase', value: 99.99 });
119
+ </script>
120
+ ```
121
+
122
+ ### `useGtmConsent()`
123
+
124
+ ```vue
125
+ <script setup>
126
+ import { useGtmConsent } from '@react-gtm-kit/vue';
127
+
128
+ const { updateConsent } = useGtmConsent();
129
+ </script>
130
+ ```
131
+
132
+ ---
133
+
134
+ ## Automatic Page Tracking
135
+
136
+ The Nuxt module automatically tracks page views on route changes. No additional setup required.
137
+
138
+ If you need custom page tracking:
139
+
140
+ ```vue
141
+ <script setup>
142
+ import { useGtm } from '@react-gtm-kit/vue';
143
+ import { useRoute } from 'vue-router';
144
+ import { watch } from 'vue';
145
+
146
+ const route = useRoute();
147
+ const { push } = useGtm();
148
+
149
+ // Custom page tracking with additional data
150
+ watch(
151
+ () => route.fullPath,
152
+ (path) => {
153
+ push({
154
+ event: 'page_view',
155
+ page_path: path,
156
+ page_title: document.title,
157
+ user_type: 'logged_in' // custom data
158
+ });
159
+ }
160
+ );
161
+ </script>
162
+ ```
163
+
164
+ ---
165
+
166
+ ## Consent Mode v2 (GDPR)
167
+
168
+ ```ts
169
+ // plugins/gtm.client.ts
170
+ import { GtmPlugin } from '@react-gtm-kit/nuxt';
171
+ import { consentPresets } from '@react-gtm-kit/core';
172
+
173
+ export default defineNuxtPlugin((nuxtApp) => {
174
+ nuxtApp.vueApp.use(GtmPlugin, {
175
+ containers: 'GTM-XXXXXX',
176
+ onBeforeInit: (client) => {
177
+ // Deny all by default for EU users
178
+ client.setConsentDefaults(consentPresets.eeaDefault, { region: ['EEA'] });
179
+ }
180
+ });
181
+ });
182
+ ```
183
+
184
+ ```vue
185
+ <!-- components/CookieBanner.vue -->
186
+ <script setup>
187
+ import { useGtmConsent } from '@react-gtm-kit/vue';
188
+ import { consentPresets } from '@react-gtm-kit/core';
189
+
190
+ const { updateConsent } = useGtmConsent();
191
+
192
+ // Accept all tracking
193
+ const acceptAll = () => updateConsent(consentPresets.allGranted);
194
+
195
+ // Reject all tracking
196
+ const rejectAll = () => updateConsent(consentPresets.eeaDefault);
197
+
198
+ // Analytics only (mixed consent)
199
+ const analyticsOnly = () => updateConsent(consentPresets.analyticsOnly);
200
+
201
+ // Partial update - only change specific categories
202
+ const customChoice = () =>
203
+ updateConsent({
204
+ analytics_storage: 'granted',
205
+ ad_storage: 'denied'
206
+ });
207
+ </script>
208
+
209
+ <template>
210
+ <div class="cookie-banner">
211
+ <button @click="acceptAll">Accept All</button>
212
+ <button @click="rejectAll">Reject All</button>
213
+ <button @click="analyticsOnly">Analytics Only</button>
214
+ </div>
215
+ </template>
216
+ ```
217
+
218
+ **Granular Updates** - Update individual categories without affecting others:
219
+
220
+ ```vue
221
+ <script setup>
222
+ const { updateConsent } = useGtmConsent();
223
+
224
+ // User later opts into ads from settings page
225
+ const enableAds = () =>
226
+ updateConsent({
227
+ ad_storage: 'granted',
228
+ ad_user_data: 'granted'
229
+ });
230
+ // analytics_storage and ad_personalization remain unchanged
231
+ </script>
232
+ ```
233
+
234
+ ---
235
+
236
+ ## SSR Considerations
237
+
238
+ The plugin file is named `gtm.client.ts` (note the `.client` suffix) to ensure it only runs on the client side. GTM requires a browser environment.
239
+
240
+ For noscript fallback (SEO), you can add this to your `app.vue`:
241
+
242
+ ```vue
243
+ <template>
244
+ <NuxtLayout>
245
+ <NuxtPage />
246
+ </NuxtLayout>
247
+
248
+ <!-- GTM noscript fallback -->
249
+ <noscript>
250
+ <iframe
251
+ src="https://www.googletagmanager.com/ns.html?id=GTM-XXXXXX"
252
+ height="0"
253
+ width="0"
254
+ style="display:none;visibility:hidden"
255
+ ></iframe>
256
+ </noscript>
257
+ </template>
258
+ ```
259
+
260
+ ---
261
+
262
+ ## Multiple Containers
263
+
264
+ ```ts
265
+ // plugins/gtm.client.ts
266
+ export default defineNuxtPlugin((nuxtApp) => {
267
+ nuxtApp.vueApp.use(GtmPlugin, {
268
+ containers: [{ id: 'GTM-MAIN' }, { id: 'GTM-ADS', queryParams: { gtm_auth: 'abc', gtm_preview: 'env-1' } }]
269
+ });
270
+ });
271
+ ```
272
+
273
+ ---
274
+
275
+ ## Runtime Config
276
+
277
+ You can use Nuxt runtime config for the GTM ID:
278
+
279
+ ```ts
280
+ // nuxt.config.ts
281
+ export default defineNuxtConfig({
282
+ runtimeConfig: {
283
+ public: {
284
+ gtmId: process.env.GTM_ID || 'GTM-XXXXXX'
285
+ }
286
+ }
287
+ });
288
+ ```
289
+
290
+ ```ts
291
+ // plugins/gtm.client.ts
292
+ export default defineNuxtPlugin((nuxtApp) => {
293
+ const config = useRuntimeConfig();
294
+
295
+ nuxtApp.vueApp.use(GtmPlugin, {
296
+ containers: config.public.gtmId
297
+ });
298
+ });
299
+ ```
300
+
301
+ ---
302
+
303
+ ## Requirements
304
+
305
+ - Nuxt 3.0+
306
+ - Vue 3.3+
307
+ - `@react-gtm-kit/core` (peer dependency)
308
+
309
+ ---
310
+
311
+ ## License
312
+
313
+ MIT
package/dist/index.cjs ADDED
@@ -0,0 +1,56 @@
1
+ 'use strict';
2
+
3
+ var vue = require('vue');
4
+ var gtmKitVue = require('@jwiedeman/gtm-kit-vue');
5
+ var gtmKit = require('@jwiedeman/gtm-kit');
6
+
7
+ var C=(n,i)=>{var o;let{trackPageViews:a=!0,pageViewEventName:u="page_view",includeQueryParams:t=!0,...s}=i;n.use(gtmKitVue.GtmPlugin,s);let e=(o=n.config.globalProperties.$gtm)==null?void 0:o.client;if(!e)throw new Error("[gtm-kit/nuxt] Failed to initialize GTM client");return e},N=gtmKitVue.useGtm,k=gtmKitVue.useGtmPush,h=gtmKitVue.useGtmConsent,v=gtmKitVue.useGtmClient,y=n=>{let{route:i,eventName:a="page_view",includeQueryParams:u=!0,additionalData:t,trackInitialPageView:s=!0}=n,e=n.client;if(!e)try{e=gtmKitVue.useGtmClient();}catch(r){}if(!e){console.warn("[gtm-kit/nuxt] useTrackPageViews: No GTM client available. Make sure GtmPlugin is installed or pass a client option.");return}let o=vue.ref(""),l=()=>u?i.fullPath:i.path,p=()=>typeof t=="function"?t():t!=null?t:{},m=()=>{let r=l();r!==o.value&&(o.value=r,e.push({event:a,page_path:r,page_location:typeof window!="undefined"?window.location.href:void 0,page_title:typeof document!="undefined"?document.title:void 0,...p()}));};vue.onMounted(()=>{s&&m();}),vue.watch(()=>i.fullPath,()=>{m();});};
8
+
9
+ Object.defineProperty(exports, 'GTM_INJECTION_KEY', {
10
+ enumerable: true,
11
+ get: function () { return gtmKitVue.GTM_INJECTION_KEY; }
12
+ });
13
+ Object.defineProperty(exports, 'GtmPlugin', {
14
+ enumerable: true,
15
+ get: function () { return gtmKitVue.GtmPlugin; }
16
+ });
17
+ Object.defineProperty(exports, 'useGtm', {
18
+ enumerable: true,
19
+ get: function () { return gtmKitVue.useGtm; }
20
+ });
21
+ Object.defineProperty(exports, 'useGtmClient', {
22
+ enumerable: true,
23
+ get: function () { return gtmKitVue.useGtmClient; }
24
+ });
25
+ Object.defineProperty(exports, 'useGtmConsent', {
26
+ enumerable: true,
27
+ get: function () { return gtmKitVue.useGtmConsent; }
28
+ });
29
+ Object.defineProperty(exports, 'useGtmPush', {
30
+ enumerable: true,
31
+ get: function () { return gtmKitVue.useGtmPush; }
32
+ });
33
+ Object.defineProperty(exports, 'useGtmReady', {
34
+ enumerable: true,
35
+ get: function () { return gtmKitVue.useGtmReady; }
36
+ });
37
+ Object.defineProperty(exports, 'consentPresets', {
38
+ enumerable: true,
39
+ get: function () { return gtmKit.consentPresets; }
40
+ });
41
+ Object.defineProperty(exports, 'pushEcommerce', {
42
+ enumerable: true,
43
+ get: function () { return gtmKit.pushEcommerce; }
44
+ });
45
+ Object.defineProperty(exports, 'pushEvent', {
46
+ enumerable: true,
47
+ get: function () { return gtmKit.pushEvent; }
48
+ });
49
+ exports.createNuxtGtmPlugin = C;
50
+ exports.useNuxtGtm = N;
51
+ exports.useNuxtGtmClient = v;
52
+ exports.useNuxtGtmConsent = h;
53
+ exports.useNuxtGtmPush = k;
54
+ exports.useTrackPageViews = y;
55
+ //# sourceMappingURL=out.js.map
56
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/module.ts","../src/index.ts"],"names":["ref","watch","onMounted","GtmPlugin","useGtm","useGtmPush","useGtmConsent","useGtmClient","createNuxtGtmPlugin","app","options","_a","_trackPageViews","_pageViewEventName","_includeQueryParams","pluginOptions","client","useNuxtGtm","useNuxtGtmPush","useNuxtGtmConsent","useNuxtGtmClient","useTrackPageViews","route","eventName","includeQueryParams","additionalData","trackInitialPageView","e","lastTrackedPath","getPagePath","getAdditionalData","trackPageView","pagePath","useGtmReady","GTM_INJECTION_KEY","consentPresets","pushEvent","pushEcommerce"],"mappings":"AAAA,OAAS,OAAAA,EAAK,SAAAC,EAAO,aAAAC,MAA2B,MAEhD,OACE,aAAAC,EACA,UAAAC,EACA,cAAAC,EACA,iBAAAC,EACA,gBAAAC,MAGK,yBAmDA,IAAMC,EAAsB,CAACC,EAAUC,IAAuC,CA7DrF,IAAAC,EA8DE,GAAM,CAEJ,eAAgBC,EAAkB,GAClC,kBAAmBC,EAAqB,YACxC,mBAAoBC,EAAsB,GAC1C,GAAGC,CACL,EAAIL,EAQJD,EAAI,IAAIN,EAAWY,CAAa,EAGhC,IAAMC,GAAUL,EAAAF,EAAI,OAAO,iBAA2C,OAAtD,YAAAE,EAA4D,OAE5E,GAAI,CAACK,EACH,MAAM,IAAI,MAAM,gDAAgD,EAGlE,OAAOA,CACT,EAeaC,EAAab,EAMbc,EAAiBb,EAMjBc,EAAoBb,EAMpBc,EAAmBb,EAgEnBc,EAAqBX,GAAyC,CACzE,GAAM,CACJ,MAAAY,EACA,UAAAC,EAAY,YACZ,mBAAAC,EAAqB,GACrB,eAAAC,EACA,qBAAAC,EAAuB,EACzB,EAAIhB,EAGAM,EAAgCN,EAAQ,OAE5C,GAAI,CAACM,EACH,GAAI,CACFA,EAAST,EAAa,CACxB,OAAQoB,EAAA,CAER,CAGF,GAAI,CAACX,EAAQ,CACX,QAAQ,KACN,sHAEF,EACA,MACF,CAEA,IAAMY,EAAkB5B,EAAY,EAAE,EAEhC6B,EAAc,IACdL,EACKF,EAAM,SAERA,EAAM,KAGTQ,EAAoB,IACpB,OAAOL,GAAmB,WACrBA,EAAe,EAEjBA,GAAA,KAAAA,EAAkB,CAAC,EAGtBM,EAAgB,IAAY,CAChC,IAAMC,EAAWH,EAAY,EAGzBG,IAAaJ,EAAgB,QAIjCA,EAAgB,MAAQI,EAExBhB,EAAQ,KAAK,CACX,MAAOO,EACP,UAAWS,EACX,cAAe,OAAO,QAAW,YAAc,OAAO,SAAS,KAAO,OACtE,WAAY,OAAO,UAAa,YAAc,SAAS,MAAQ,OAC/D,GAAGF,EAAkB,CACvB,CAAC,EACH,EAGA5B,EAAU,IAAM,CACVwB,GACFK,EAAc,CAElB,CAAC,EAGD9B,EACE,IAAMqB,EAAM,SACZ,IAAM,CACJS,EAAc,CAChB,CACF,CACF,ECzPA,OACE,UAAA3B,EACA,cAAAC,EACA,iBAAAC,EACA,gBAAAC,EACA,eAAA0B,EACA,aAAA9B,EACA,qBAAA+B,MACK,yBAYP,OAAS,kBAAAC,EAAgB,aAAAC,EAAW,iBAAAC,MAAqB","sourcesContent":["import { ref, watch, onMounted, type App } from 'vue';\nimport { type GtmClient } from '@jwiedeman/gtm-kit';\nimport {\n GtmPlugin,\n useGtm,\n useGtmPush,\n useGtmConsent,\n useGtmClient,\n type GtmPluginOptions,\n type GtmContext\n} from '@jwiedeman/gtm-kit-vue';\n\n/**\n * Options for the Nuxt GTM module.\n * Extends the Vue plugin options with Nuxt-specific features.\n */\nexport interface NuxtGtmOptions extends GtmPluginOptions {\n /**\n * Whether to automatically track page views on route changes.\n * @default true\n */\n trackPageViews?: boolean;\n\n /**\n * Custom page view event name.\n * @default 'page_view'\n */\n pageViewEventName?: string;\n\n /**\n * Whether to include query parameters in page path.\n * @default true\n */\n includeQueryParams?: boolean;\n}\n\n/**\n * Extended context for Nuxt with additional helpers.\n */\nexport interface NuxtGtmContext extends GtmContext {\n /** Track a page view manually */\n trackPageView: (path?: string, additionalData?: Record<string, unknown>) => void;\n}\n\n/**\n * Creates a Nuxt plugin for GTM Kit.\n * Use this in your Nuxt plugins directory.\n *\n * @example\n * ```ts\n * // plugins/gtm.client.ts\n * import { createNuxtGtmPlugin } from '@jwiedeman/gtm-kit-nuxt';\n *\n * export default defineNuxtPlugin((nuxtApp) => {\n * createNuxtGtmPlugin(nuxtApp.vueApp, {\n * containers: 'GTM-XXXXXX',\n * trackPageViews: true\n * });\n * });\n * ```\n */\nexport const createNuxtGtmPlugin = (app: App, options: NuxtGtmOptions): GtmClient => {\n const {\n // These options are extracted for potential future auto-tracking features\n trackPageViews: _trackPageViews = true,\n pageViewEventName: _pageViewEventName = 'page_view',\n includeQueryParams: _includeQueryParams = true,\n ...pluginOptions\n } = options;\n\n // Silence unused variable warnings - these are reserved for future auto-tracking\n void _trackPageViews;\n void _pageViewEventName;\n void _includeQueryParams;\n\n // Install the Vue plugin\n app.use(GtmPlugin, pluginOptions);\n\n // Get the client from the Vue plugin\n const client = (app.config.globalProperties as { $gtm?: GtmContext }).$gtm?.client;\n\n if (!client) {\n throw new Error('[gtm-kit/nuxt] Failed to initialize GTM client');\n }\n\n return client;\n};\n\n/**\n * Composable for accessing the full GTM context in Nuxt.\n * This is an alias for useGtm() from @jwiedeman/gtm-kit-vue.\n *\n * @example\n * ```vue\n * <script setup>\n * const { push, client } = useNuxtGtm();\n *\n * push({ event: 'custom_event' });\n * </script>\n * ```\n */\nexport const useNuxtGtm = useGtm;\n\n/**\n * Composable for pushing events in Nuxt.\n * This is an alias for useGtmPush() from @jwiedeman/gtm-kit-vue.\n */\nexport const useNuxtGtmPush = useGtmPush;\n\n/**\n * Composable for consent management in Nuxt.\n * This is an alias for useGtmConsent() from @jwiedeman/gtm-kit-vue.\n */\nexport const useNuxtGtmConsent = useGtmConsent;\n\n/**\n * Composable for accessing the raw GTM client in Nuxt.\n * This is an alias for useGtmClient() from @jwiedeman/gtm-kit-vue.\n */\nexport const useNuxtGtmClient = useGtmClient;\n\n/**\n * Options for the useTrackPageViews composable.\n */\nexport interface TrackPageViewsOptions {\n /**\n * The GTM client instance to use.\n * If not provided, will use the client from the Vue plugin context.\n */\n client?: GtmClient;\n\n /**\n * Reactive route object to watch for changes.\n * Use useRoute() from Nuxt.\n */\n route: {\n fullPath: string;\n path: string;\n query?: Record<string, unknown>;\n };\n\n /**\n * Custom page view event name.\n * @default 'page_view'\n */\n eventName?: string;\n\n /**\n * Whether to include query parameters in page path.\n * @default true\n */\n includeQueryParams?: boolean;\n\n /**\n * Additional data to include with each page view event.\n */\n additionalData?: Record<string, unknown> | (() => Record<string, unknown>);\n\n /**\n * Whether to track the initial page view on mount.\n * @default true\n */\n trackInitialPageView?: boolean;\n}\n\n/**\n * Composable for automatic page view tracking with Nuxt Router.\n *\n * @example\n * ```vue\n * <script setup>\n * import { useTrackPageViews } from '@jwiedeman/gtm-kit-nuxt';\n *\n * const route = useRoute();\n *\n * useTrackPageViews({\n * route,\n * eventName: 'page_view',\n * additionalData: { site_section: 'main' }\n * });\n * </script>\n * ```\n */\nexport const useTrackPageViews = (options: TrackPageViewsOptions): void => {\n const {\n route,\n eventName = 'page_view',\n includeQueryParams = true,\n additionalData,\n trackInitialPageView = true\n } = options;\n\n // Try to get client from options or from context\n let client: GtmClient | undefined = options.client;\n\n if (!client) {\n try {\n client = useGtmClient();\n } catch {\n // Client not available from context, will throw later if needed\n }\n }\n\n if (!client) {\n console.warn(\n '[gtm-kit/nuxt] useTrackPageViews: No GTM client available. ' +\n 'Make sure GtmPlugin is installed or pass a client option.'\n );\n return;\n }\n\n const lastTrackedPath = ref<string>('');\n\n const getPagePath = (): string => {\n if (includeQueryParams) {\n return route.fullPath;\n }\n return route.path;\n };\n\n const getAdditionalData = (): Record<string, unknown> => {\n if (typeof additionalData === 'function') {\n return additionalData();\n }\n return additionalData ?? {};\n };\n\n const trackPageView = (): void => {\n const pagePath = getPagePath();\n\n // Skip if this path was already tracked\n if (pagePath === lastTrackedPath.value) {\n return;\n }\n\n lastTrackedPath.value = pagePath;\n\n client!.push({\n event: eventName,\n page_path: pagePath,\n page_location: typeof window !== 'undefined' ? window.location.href : undefined,\n page_title: typeof document !== 'undefined' ? document.title : undefined,\n ...getAdditionalData()\n });\n };\n\n // Track initial page view on mount if enabled\n onMounted(() => {\n if (trackInitialPageView) {\n trackPageView();\n }\n });\n\n // Watch for route changes\n watch(\n () => route.fullPath,\n () => {\n trackPageView();\n }\n );\n};\n\n// Note: Type augmentation for NuxtApp.$gtm should be done in the user's project\n// by adding a type declaration file with:\n//\n// declare module '#app' {\n// interface NuxtApp {\n// $gtm: import('@jwiedeman/gtm-kit-vue').GtmContext;\n// }\n// }\n","export type { NuxtGtmOptions, NuxtGtmContext } from './module';\nexport {\n createNuxtGtmPlugin,\n useNuxtGtm,\n useNuxtGtmPush,\n useNuxtGtmConsent,\n useNuxtGtmClient,\n useTrackPageViews\n} from './module';\n\n// Re-export Vue composables for convenience\nexport {\n useGtm,\n useGtmPush,\n useGtmConsent,\n useGtmClient,\n useGtmReady,\n GtmPlugin,\n GTM_INJECTION_KEY\n} from '@jwiedeman/gtm-kit-vue';\n\n// Re-export core types for convenience\nexport type {\n CreateGtmClientOptions,\n GtmClient,\n ConsentState,\n ConsentRegionOptions,\n DataLayerValue,\n ScriptLoadState\n} from '@jwiedeman/gtm-kit';\n\nexport { consentPresets, pushEvent, pushEcommerce } from '@jwiedeman/gtm-kit';\n"]}
@@ -0,0 +1,142 @@
1
+ import * as _jwiedeman_gtm_kit_vue from '@jwiedeman/gtm-kit-vue';
2
+ import { GtmPluginOptions, GtmContext } from '@jwiedeman/gtm-kit-vue';
3
+ export { GTM_INJECTION_KEY, GtmPlugin, useGtm, useGtmClient, useGtmConsent, useGtmPush, useGtmReady } from '@jwiedeman/gtm-kit-vue';
4
+ import * as _jwiedeman_gtm_kit from '@jwiedeman/gtm-kit';
5
+ import { GtmClient } from '@jwiedeman/gtm-kit';
6
+ export { ConsentRegionOptions, ConsentState, CreateGtmClientOptions, DataLayerValue, GtmClient, ScriptLoadState, consentPresets, pushEcommerce, pushEvent } from '@jwiedeman/gtm-kit';
7
+ import { App } from 'vue';
8
+
9
+ /**
10
+ * Options for the Nuxt GTM module.
11
+ * Extends the Vue plugin options with Nuxt-specific features.
12
+ */
13
+ interface NuxtGtmOptions extends GtmPluginOptions {
14
+ /**
15
+ * Whether to automatically track page views on route changes.
16
+ * @default true
17
+ */
18
+ trackPageViews?: boolean;
19
+ /**
20
+ * Custom page view event name.
21
+ * @default 'page_view'
22
+ */
23
+ pageViewEventName?: string;
24
+ /**
25
+ * Whether to include query parameters in page path.
26
+ * @default true
27
+ */
28
+ includeQueryParams?: boolean;
29
+ }
30
+ /**
31
+ * Extended context for Nuxt with additional helpers.
32
+ */
33
+ interface NuxtGtmContext extends GtmContext {
34
+ /** Track a page view manually */
35
+ trackPageView: (path?: string, additionalData?: Record<string, unknown>) => void;
36
+ }
37
+ /**
38
+ * Creates a Nuxt plugin for GTM Kit.
39
+ * Use this in your Nuxt plugins directory.
40
+ *
41
+ * @example
42
+ * ```ts
43
+ * // plugins/gtm.client.ts
44
+ * import { createNuxtGtmPlugin } from '@jwiedeman/gtm-kit-nuxt';
45
+ *
46
+ * export default defineNuxtPlugin((nuxtApp) => {
47
+ * createNuxtGtmPlugin(nuxtApp.vueApp, {
48
+ * containers: 'GTM-XXXXXX',
49
+ * trackPageViews: true
50
+ * });
51
+ * });
52
+ * ```
53
+ */
54
+ declare const createNuxtGtmPlugin: (app: App, options: NuxtGtmOptions) => GtmClient;
55
+ /**
56
+ * Composable for accessing the full GTM context in Nuxt.
57
+ * This is an alias for useGtm() from @jwiedeman/gtm-kit-vue.
58
+ *
59
+ * @example
60
+ * ```vue
61
+ * <script setup>
62
+ * const { push, client } = useNuxtGtm();
63
+ *
64
+ * push({ event: 'custom_event' });
65
+ * </script>
66
+ * ```
67
+ */
68
+ declare const useNuxtGtm: () => GtmContext;
69
+ /**
70
+ * Composable for pushing events in Nuxt.
71
+ * This is an alias for useGtmPush() from @jwiedeman/gtm-kit-vue.
72
+ */
73
+ declare const useNuxtGtmPush: () => (value: _jwiedeman_gtm_kit.DataLayerValue) => void;
74
+ /**
75
+ * Composable for consent management in Nuxt.
76
+ * This is an alias for useGtmConsent() from @jwiedeman/gtm-kit-vue.
77
+ */
78
+ declare const useNuxtGtmConsent: () => _jwiedeman_gtm_kit_vue.GtmConsentApi;
79
+ /**
80
+ * Composable for accessing the raw GTM client in Nuxt.
81
+ * This is an alias for useGtmClient() from @jwiedeman/gtm-kit-vue.
82
+ */
83
+ declare const useNuxtGtmClient: () => GtmClient;
84
+ /**
85
+ * Options for the useTrackPageViews composable.
86
+ */
87
+ interface TrackPageViewsOptions {
88
+ /**
89
+ * The GTM client instance to use.
90
+ * If not provided, will use the client from the Vue plugin context.
91
+ */
92
+ client?: GtmClient;
93
+ /**
94
+ * Reactive route object to watch for changes.
95
+ * Use useRoute() from Nuxt.
96
+ */
97
+ route: {
98
+ fullPath: string;
99
+ path: string;
100
+ query?: Record<string, unknown>;
101
+ };
102
+ /**
103
+ * Custom page view event name.
104
+ * @default 'page_view'
105
+ */
106
+ eventName?: string;
107
+ /**
108
+ * Whether to include query parameters in page path.
109
+ * @default true
110
+ */
111
+ includeQueryParams?: boolean;
112
+ /**
113
+ * Additional data to include with each page view event.
114
+ */
115
+ additionalData?: Record<string, unknown> | (() => Record<string, unknown>);
116
+ /**
117
+ * Whether to track the initial page view on mount.
118
+ * @default true
119
+ */
120
+ trackInitialPageView?: boolean;
121
+ }
122
+ /**
123
+ * Composable for automatic page view tracking with Nuxt Router.
124
+ *
125
+ * @example
126
+ * ```vue
127
+ * <script setup>
128
+ * import { useTrackPageViews } from '@jwiedeman/gtm-kit-nuxt';
129
+ *
130
+ * const route = useRoute();
131
+ *
132
+ * useTrackPageViews({
133
+ * route,
134
+ * eventName: 'page_view',
135
+ * additionalData: { site_section: 'main' }
136
+ * });
137
+ * </script>
138
+ * ```
139
+ */
140
+ declare const useTrackPageViews: (options: TrackPageViewsOptions) => void;
141
+
142
+ export { NuxtGtmContext, NuxtGtmOptions, createNuxtGtmPlugin, useNuxtGtm, useNuxtGtmClient, useNuxtGtmConsent, useNuxtGtmPush, useTrackPageViews };
@@ -0,0 +1,142 @@
1
+ import * as _jwiedeman_gtm_kit_vue from '@jwiedeman/gtm-kit-vue';
2
+ import { GtmPluginOptions, GtmContext } from '@jwiedeman/gtm-kit-vue';
3
+ export { GTM_INJECTION_KEY, GtmPlugin, useGtm, useGtmClient, useGtmConsent, useGtmPush, useGtmReady } from '@jwiedeman/gtm-kit-vue';
4
+ import * as _jwiedeman_gtm_kit from '@jwiedeman/gtm-kit';
5
+ import { GtmClient } from '@jwiedeman/gtm-kit';
6
+ export { ConsentRegionOptions, ConsentState, CreateGtmClientOptions, DataLayerValue, GtmClient, ScriptLoadState, consentPresets, pushEcommerce, pushEvent } from '@jwiedeman/gtm-kit';
7
+ import { App } from 'vue';
8
+
9
+ /**
10
+ * Options for the Nuxt GTM module.
11
+ * Extends the Vue plugin options with Nuxt-specific features.
12
+ */
13
+ interface NuxtGtmOptions extends GtmPluginOptions {
14
+ /**
15
+ * Whether to automatically track page views on route changes.
16
+ * @default true
17
+ */
18
+ trackPageViews?: boolean;
19
+ /**
20
+ * Custom page view event name.
21
+ * @default 'page_view'
22
+ */
23
+ pageViewEventName?: string;
24
+ /**
25
+ * Whether to include query parameters in page path.
26
+ * @default true
27
+ */
28
+ includeQueryParams?: boolean;
29
+ }
30
+ /**
31
+ * Extended context for Nuxt with additional helpers.
32
+ */
33
+ interface NuxtGtmContext extends GtmContext {
34
+ /** Track a page view manually */
35
+ trackPageView: (path?: string, additionalData?: Record<string, unknown>) => void;
36
+ }
37
+ /**
38
+ * Creates a Nuxt plugin for GTM Kit.
39
+ * Use this in your Nuxt plugins directory.
40
+ *
41
+ * @example
42
+ * ```ts
43
+ * // plugins/gtm.client.ts
44
+ * import { createNuxtGtmPlugin } from '@jwiedeman/gtm-kit-nuxt';
45
+ *
46
+ * export default defineNuxtPlugin((nuxtApp) => {
47
+ * createNuxtGtmPlugin(nuxtApp.vueApp, {
48
+ * containers: 'GTM-XXXXXX',
49
+ * trackPageViews: true
50
+ * });
51
+ * });
52
+ * ```
53
+ */
54
+ declare const createNuxtGtmPlugin: (app: App, options: NuxtGtmOptions) => GtmClient;
55
+ /**
56
+ * Composable for accessing the full GTM context in Nuxt.
57
+ * This is an alias for useGtm() from @jwiedeman/gtm-kit-vue.
58
+ *
59
+ * @example
60
+ * ```vue
61
+ * <script setup>
62
+ * const { push, client } = useNuxtGtm();
63
+ *
64
+ * push({ event: 'custom_event' });
65
+ * </script>
66
+ * ```
67
+ */
68
+ declare const useNuxtGtm: () => GtmContext;
69
+ /**
70
+ * Composable for pushing events in Nuxt.
71
+ * This is an alias for useGtmPush() from @jwiedeman/gtm-kit-vue.
72
+ */
73
+ declare const useNuxtGtmPush: () => (value: _jwiedeman_gtm_kit.DataLayerValue) => void;
74
+ /**
75
+ * Composable for consent management in Nuxt.
76
+ * This is an alias for useGtmConsent() from @jwiedeman/gtm-kit-vue.
77
+ */
78
+ declare const useNuxtGtmConsent: () => _jwiedeman_gtm_kit_vue.GtmConsentApi;
79
+ /**
80
+ * Composable for accessing the raw GTM client in Nuxt.
81
+ * This is an alias for useGtmClient() from @jwiedeman/gtm-kit-vue.
82
+ */
83
+ declare const useNuxtGtmClient: () => GtmClient;
84
+ /**
85
+ * Options for the useTrackPageViews composable.
86
+ */
87
+ interface TrackPageViewsOptions {
88
+ /**
89
+ * The GTM client instance to use.
90
+ * If not provided, will use the client from the Vue plugin context.
91
+ */
92
+ client?: GtmClient;
93
+ /**
94
+ * Reactive route object to watch for changes.
95
+ * Use useRoute() from Nuxt.
96
+ */
97
+ route: {
98
+ fullPath: string;
99
+ path: string;
100
+ query?: Record<string, unknown>;
101
+ };
102
+ /**
103
+ * Custom page view event name.
104
+ * @default 'page_view'
105
+ */
106
+ eventName?: string;
107
+ /**
108
+ * Whether to include query parameters in page path.
109
+ * @default true
110
+ */
111
+ includeQueryParams?: boolean;
112
+ /**
113
+ * Additional data to include with each page view event.
114
+ */
115
+ additionalData?: Record<string, unknown> | (() => Record<string, unknown>);
116
+ /**
117
+ * Whether to track the initial page view on mount.
118
+ * @default true
119
+ */
120
+ trackInitialPageView?: boolean;
121
+ }
122
+ /**
123
+ * Composable for automatic page view tracking with Nuxt Router.
124
+ *
125
+ * @example
126
+ * ```vue
127
+ * <script setup>
128
+ * import { useTrackPageViews } from '@jwiedeman/gtm-kit-nuxt';
129
+ *
130
+ * const route = useRoute();
131
+ *
132
+ * useTrackPageViews({
133
+ * route,
134
+ * eventName: 'page_view',
135
+ * additionalData: { site_section: 'main' }
136
+ * });
137
+ * </script>
138
+ * ```
139
+ */
140
+ declare const useTrackPageViews: (options: TrackPageViewsOptions) => void;
141
+
142
+ export { NuxtGtmContext, NuxtGtmOptions, createNuxtGtmPlugin, useNuxtGtm, useNuxtGtmClient, useNuxtGtmConsent, useNuxtGtmPush, useTrackPageViews };
package/dist/index.js ADDED
@@ -0,0 +1,10 @@
1
+ import { ref, onMounted, watch } from 'vue';
2
+ import { GtmPlugin, useGtm, useGtmPush, useGtmConsent, useGtmClient } from '@jwiedeman/gtm-kit-vue';
3
+ export { GTM_INJECTION_KEY, GtmPlugin, useGtm, useGtmClient, useGtmConsent, useGtmPush, useGtmReady } from '@jwiedeman/gtm-kit-vue';
4
+ export { consentPresets, pushEcommerce, pushEvent } from '@jwiedeman/gtm-kit';
5
+
6
+ var C=(n,i)=>{var o;let{trackPageViews:a=!0,pageViewEventName:u="page_view",includeQueryParams:t=!0,...s}=i;n.use(GtmPlugin,s);let e=(o=n.config.globalProperties.$gtm)==null?void 0:o.client;if(!e)throw new Error("[gtm-kit/nuxt] Failed to initialize GTM client");return e},N=useGtm,k=useGtmPush,h=useGtmConsent,v=useGtmClient,y=n=>{let{route:i,eventName:a="page_view",includeQueryParams:u=!0,additionalData:t,trackInitialPageView:s=!0}=n,e=n.client;if(!e)try{e=useGtmClient();}catch(r){}if(!e){console.warn("[gtm-kit/nuxt] useTrackPageViews: No GTM client available. Make sure GtmPlugin is installed or pass a client option.");return}let o=ref(""),l=()=>u?i.fullPath:i.path,p=()=>typeof t=="function"?t():t!=null?t:{},m=()=>{let r=l();r!==o.value&&(o.value=r,e.push({event:a,page_path:r,page_location:typeof window!="undefined"?window.location.href:void 0,page_title:typeof document!="undefined"?document.title:void 0,...p()}));};onMounted(()=>{s&&m();}),watch(()=>i.fullPath,()=>{m();});};
7
+
8
+ export { C as createNuxtGtmPlugin, N as useNuxtGtm, v as useNuxtGtmClient, h as useNuxtGtmConsent, k as useNuxtGtmPush, y as useTrackPageViews };
9
+ //# sourceMappingURL=out.js.map
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/module.ts","../src/index.ts"],"names":["ref","watch","onMounted","GtmPlugin","useGtm","useGtmPush","useGtmConsent","useGtmClient","createNuxtGtmPlugin","app","options","_a","_trackPageViews","_pageViewEventName","_includeQueryParams","pluginOptions","client","useNuxtGtm","useNuxtGtmPush","useNuxtGtmConsent","useNuxtGtmClient","useTrackPageViews","route","eventName","includeQueryParams","additionalData","trackInitialPageView","e","lastTrackedPath","getPagePath","getAdditionalData","trackPageView","pagePath","useGtmReady","GTM_INJECTION_KEY","consentPresets","pushEvent","pushEcommerce"],"mappings":"AAAA,OAAS,OAAAA,EAAK,SAAAC,EAAO,aAAAC,MAA2B,MAEhD,OACE,aAAAC,EACA,UAAAC,EACA,cAAAC,EACA,iBAAAC,EACA,gBAAAC,MAGK,yBAmDA,IAAMC,EAAsB,CAACC,EAAUC,IAAuC,CA7DrF,IAAAC,EA8DE,GAAM,CAEJ,eAAgBC,EAAkB,GAClC,kBAAmBC,EAAqB,YACxC,mBAAoBC,EAAsB,GAC1C,GAAGC,CACL,EAAIL,EAQJD,EAAI,IAAIN,EAAWY,CAAa,EAGhC,IAAMC,GAAUL,EAAAF,EAAI,OAAO,iBAA2C,OAAtD,YAAAE,EAA4D,OAE5E,GAAI,CAACK,EACH,MAAM,IAAI,MAAM,gDAAgD,EAGlE,OAAOA,CACT,EAeaC,EAAab,EAMbc,EAAiBb,EAMjBc,EAAoBb,EAMpBc,EAAmBb,EAgEnBc,EAAqBX,GAAyC,CACzE,GAAM,CACJ,MAAAY,EACA,UAAAC,EAAY,YACZ,mBAAAC,EAAqB,GACrB,eAAAC,EACA,qBAAAC,EAAuB,EACzB,EAAIhB,EAGAM,EAAgCN,EAAQ,OAE5C,GAAI,CAACM,EACH,GAAI,CACFA,EAAST,EAAa,CACxB,OAAQoB,EAAA,CAER,CAGF,GAAI,CAACX,EAAQ,CACX,QAAQ,KACN,sHAEF,EACA,MACF,CAEA,IAAMY,EAAkB5B,EAAY,EAAE,EAEhC6B,EAAc,IACdL,EACKF,EAAM,SAERA,EAAM,KAGTQ,EAAoB,IACpB,OAAOL,GAAmB,WACrBA,EAAe,EAEjBA,GAAA,KAAAA,EAAkB,CAAC,EAGtBM,EAAgB,IAAY,CAChC,IAAMC,EAAWH,EAAY,EAGzBG,IAAaJ,EAAgB,QAIjCA,EAAgB,MAAQI,EAExBhB,EAAQ,KAAK,CACX,MAAOO,EACP,UAAWS,EACX,cAAe,OAAO,QAAW,YAAc,OAAO,SAAS,KAAO,OACtE,WAAY,OAAO,UAAa,YAAc,SAAS,MAAQ,OAC/D,GAAGF,EAAkB,CACvB,CAAC,EACH,EAGA5B,EAAU,IAAM,CACVwB,GACFK,EAAc,CAElB,CAAC,EAGD9B,EACE,IAAMqB,EAAM,SACZ,IAAM,CACJS,EAAc,CAChB,CACF,CACF,ECzPA,OACE,UAAA3B,EACA,cAAAC,EACA,iBAAAC,EACA,gBAAAC,EACA,eAAA0B,EACA,aAAA9B,EACA,qBAAA+B,MACK,yBAYP,OAAS,kBAAAC,EAAgB,aAAAC,EAAW,iBAAAC,MAAqB","sourcesContent":["import { ref, watch, onMounted, type App } from 'vue';\nimport { type GtmClient } from '@jwiedeman/gtm-kit';\nimport {\n GtmPlugin,\n useGtm,\n useGtmPush,\n useGtmConsent,\n useGtmClient,\n type GtmPluginOptions,\n type GtmContext\n} from '@jwiedeman/gtm-kit-vue';\n\n/**\n * Options for the Nuxt GTM module.\n * Extends the Vue plugin options with Nuxt-specific features.\n */\nexport interface NuxtGtmOptions extends GtmPluginOptions {\n /**\n * Whether to automatically track page views on route changes.\n * @default true\n */\n trackPageViews?: boolean;\n\n /**\n * Custom page view event name.\n * @default 'page_view'\n */\n pageViewEventName?: string;\n\n /**\n * Whether to include query parameters in page path.\n * @default true\n */\n includeQueryParams?: boolean;\n}\n\n/**\n * Extended context for Nuxt with additional helpers.\n */\nexport interface NuxtGtmContext extends GtmContext {\n /** Track a page view manually */\n trackPageView: (path?: string, additionalData?: Record<string, unknown>) => void;\n}\n\n/**\n * Creates a Nuxt plugin for GTM Kit.\n * Use this in your Nuxt plugins directory.\n *\n * @example\n * ```ts\n * // plugins/gtm.client.ts\n * import { createNuxtGtmPlugin } from '@jwiedeman/gtm-kit-nuxt';\n *\n * export default defineNuxtPlugin((nuxtApp) => {\n * createNuxtGtmPlugin(nuxtApp.vueApp, {\n * containers: 'GTM-XXXXXX',\n * trackPageViews: true\n * });\n * });\n * ```\n */\nexport const createNuxtGtmPlugin = (app: App, options: NuxtGtmOptions): GtmClient => {\n const {\n // These options are extracted for potential future auto-tracking features\n trackPageViews: _trackPageViews = true,\n pageViewEventName: _pageViewEventName = 'page_view',\n includeQueryParams: _includeQueryParams = true,\n ...pluginOptions\n } = options;\n\n // Silence unused variable warnings - these are reserved for future auto-tracking\n void _trackPageViews;\n void _pageViewEventName;\n void _includeQueryParams;\n\n // Install the Vue plugin\n app.use(GtmPlugin, pluginOptions);\n\n // Get the client from the Vue plugin\n const client = (app.config.globalProperties as { $gtm?: GtmContext }).$gtm?.client;\n\n if (!client) {\n throw new Error('[gtm-kit/nuxt] Failed to initialize GTM client');\n }\n\n return client;\n};\n\n/**\n * Composable for accessing the full GTM context in Nuxt.\n * This is an alias for useGtm() from @jwiedeman/gtm-kit-vue.\n *\n * @example\n * ```vue\n * <script setup>\n * const { push, client } = useNuxtGtm();\n *\n * push({ event: 'custom_event' });\n * </script>\n * ```\n */\nexport const useNuxtGtm = useGtm;\n\n/**\n * Composable for pushing events in Nuxt.\n * This is an alias for useGtmPush() from @jwiedeman/gtm-kit-vue.\n */\nexport const useNuxtGtmPush = useGtmPush;\n\n/**\n * Composable for consent management in Nuxt.\n * This is an alias for useGtmConsent() from @jwiedeman/gtm-kit-vue.\n */\nexport const useNuxtGtmConsent = useGtmConsent;\n\n/**\n * Composable for accessing the raw GTM client in Nuxt.\n * This is an alias for useGtmClient() from @jwiedeman/gtm-kit-vue.\n */\nexport const useNuxtGtmClient = useGtmClient;\n\n/**\n * Options for the useTrackPageViews composable.\n */\nexport interface TrackPageViewsOptions {\n /**\n * The GTM client instance to use.\n * If not provided, will use the client from the Vue plugin context.\n */\n client?: GtmClient;\n\n /**\n * Reactive route object to watch for changes.\n * Use useRoute() from Nuxt.\n */\n route: {\n fullPath: string;\n path: string;\n query?: Record<string, unknown>;\n };\n\n /**\n * Custom page view event name.\n * @default 'page_view'\n */\n eventName?: string;\n\n /**\n * Whether to include query parameters in page path.\n * @default true\n */\n includeQueryParams?: boolean;\n\n /**\n * Additional data to include with each page view event.\n */\n additionalData?: Record<string, unknown> | (() => Record<string, unknown>);\n\n /**\n * Whether to track the initial page view on mount.\n * @default true\n */\n trackInitialPageView?: boolean;\n}\n\n/**\n * Composable for automatic page view tracking with Nuxt Router.\n *\n * @example\n * ```vue\n * <script setup>\n * import { useTrackPageViews } from '@jwiedeman/gtm-kit-nuxt';\n *\n * const route = useRoute();\n *\n * useTrackPageViews({\n * route,\n * eventName: 'page_view',\n * additionalData: { site_section: 'main' }\n * });\n * </script>\n * ```\n */\nexport const useTrackPageViews = (options: TrackPageViewsOptions): void => {\n const {\n route,\n eventName = 'page_view',\n includeQueryParams = true,\n additionalData,\n trackInitialPageView = true\n } = options;\n\n // Try to get client from options or from context\n let client: GtmClient | undefined = options.client;\n\n if (!client) {\n try {\n client = useGtmClient();\n } catch {\n // Client not available from context, will throw later if needed\n }\n }\n\n if (!client) {\n console.warn(\n '[gtm-kit/nuxt] useTrackPageViews: No GTM client available. ' +\n 'Make sure GtmPlugin is installed or pass a client option.'\n );\n return;\n }\n\n const lastTrackedPath = ref<string>('');\n\n const getPagePath = (): string => {\n if (includeQueryParams) {\n return route.fullPath;\n }\n return route.path;\n };\n\n const getAdditionalData = (): Record<string, unknown> => {\n if (typeof additionalData === 'function') {\n return additionalData();\n }\n return additionalData ?? {};\n };\n\n const trackPageView = (): void => {\n const pagePath = getPagePath();\n\n // Skip if this path was already tracked\n if (pagePath === lastTrackedPath.value) {\n return;\n }\n\n lastTrackedPath.value = pagePath;\n\n client!.push({\n event: eventName,\n page_path: pagePath,\n page_location: typeof window !== 'undefined' ? window.location.href : undefined,\n page_title: typeof document !== 'undefined' ? document.title : undefined,\n ...getAdditionalData()\n });\n };\n\n // Track initial page view on mount if enabled\n onMounted(() => {\n if (trackInitialPageView) {\n trackPageView();\n }\n });\n\n // Watch for route changes\n watch(\n () => route.fullPath,\n () => {\n trackPageView();\n }\n );\n};\n\n// Note: Type augmentation for NuxtApp.$gtm should be done in the user's project\n// by adding a type declaration file with:\n//\n// declare module '#app' {\n// interface NuxtApp {\n// $gtm: import('@jwiedeman/gtm-kit-vue').GtmContext;\n// }\n// }\n","export type { NuxtGtmOptions, NuxtGtmContext } from './module';\nexport {\n createNuxtGtmPlugin,\n useNuxtGtm,\n useNuxtGtmPush,\n useNuxtGtmConsent,\n useNuxtGtmClient,\n useTrackPageViews\n} from './module';\n\n// Re-export Vue composables for convenience\nexport {\n useGtm,\n useGtmPush,\n useGtmConsent,\n useGtmClient,\n useGtmReady,\n GtmPlugin,\n GTM_INJECTION_KEY\n} from '@jwiedeman/gtm-kit-vue';\n\n// Re-export core types for convenience\nexport type {\n CreateGtmClientOptions,\n GtmClient,\n ConsentState,\n ConsentRegionOptions,\n DataLayerValue,\n ScriptLoadState\n} from '@jwiedeman/gtm-kit';\n\nexport { consentPresets, pushEvent, pushEcommerce } from '@jwiedeman/gtm-kit';\n"]}
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "@jwiedeman/gtm-kit-nuxt",
3
+ "version": "1.0.1",
4
+ "description": "Nuxt 3 module for GTM Kit - Google Tag Manager integration with auto page tracking.",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "https://github.com/jwiedeman/GTM-Kit.git",
8
+ "directory": "packages/nuxt"
9
+ },
10
+ "author": "jwiedeman",
11
+ "keywords": [
12
+ "gtm",
13
+ "google-tag-manager",
14
+ "nuxt",
15
+ "nuxt3",
16
+ "module"
17
+ ],
18
+ "license": "MIT",
19
+ "publishConfig": {
20
+ "access": "public"
21
+ },
22
+ "type": "module",
23
+ "main": "dist/index.cjs",
24
+ "module": "dist/index.js",
25
+ "types": "dist/index.d.ts",
26
+ "exports": {
27
+ ".": {
28
+ "types": "./dist/index.d.ts",
29
+ "import": "./dist/index.js",
30
+ "require": "./dist/index.cjs"
31
+ }
32
+ },
33
+ "files": [
34
+ "dist"
35
+ ],
36
+ "scripts": {
37
+ "build": "tsup",
38
+ "clean": "rm -rf dist",
39
+ "lint": "eslint --max-warnings=0 \"src/**/*.{ts,tsx}\"",
40
+ "test": "jest --config ./jest.config.cjs --runInBand",
41
+ "typecheck": "tsc --noEmit"
42
+ },
43
+ "dependencies": {
44
+ "@jwiedeman/gtm-kit": "^1.0.1",
45
+ "@jwiedeman/gtm-kit-vue": "^1.0.1"
46
+ },
47
+ "peerDependencies": {
48
+ "nuxt": "^3.0.0",
49
+ "vue": "^3.3.0"
50
+ },
51
+ "devDependencies": {
52
+ "@vue/test-utils": "^2.4.6",
53
+ "nuxt": "^3.11.0",
54
+ "vue": "^3.4.21",
55
+ "tslib": "^2.6.2"
56
+ }
57
+ }