npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@jwiedeman/gtm-kit-nuxt

v1.1.5

Published

Nuxt 3 module for GTM Kit - Google Tag Manager integration with auto page tracking and runtime config.

Downloads

658

Readme

@jwiedeman/gtm-kit-nuxt

CI Coverage npm version Bundle Size TypeScript License: MIT Nuxt 3

Nuxt 3 module for Google Tag Manager. Auto page tracking. Zero config.

The Nuxt adapter for GTM Kit - native module with automatic page tracking and SSR support.


Installation

npm install @jwiedeman/gtm-kit @jwiedeman/gtm-kit-nuxt
yarn add @jwiedeman/gtm-kit @jwiedeman/gtm-kit-nuxt
pnpm add @jwiedeman/gtm-kit @jwiedeman/gtm-kit-nuxt

Quick Start

Step 1: Create Plugin

// plugins/gtm.client.ts
import { GtmPlugin } from '@jwiedeman/gtm-kit-nuxt';

export default defineNuxtPlugin((nuxtApp) => {
  nuxtApp.vueApp.use(GtmPlugin, { containers: 'GTM-XXXXXX' });
});

Step 2: Push Events

<script setup>
import { useGtm } from '@jwiedeman/gtm-kit-vue';

const { push } = useGtm();

push({ event: 'page_view' });
</script>

That's it! GTM is running with automatic page tracking.


Features

| Feature | Description | | ---------------------- | ----------------------------------- | | Native Nuxt Module | Built specifically for Nuxt 3 | | Auto Page Tracking | Tracks route changes automatically | | SSR Support | Server-side rendering compatible | | Composables | Uses Vue composables under the hood | | TypeScript | Full type definitions included | | Consent Mode v2 | Built-in GDPR compliance |


Plugin Configuration

// plugins/gtm.client.ts
import { GtmPlugin } from '@jwiedeman/gtm-kit-nuxt';
import { consentPresets } from '@jwiedeman/gtm-kit';

export default defineNuxtPlugin((nuxtApp) => {
  nuxtApp.vueApp.use(GtmPlugin, {
    containers: 'GTM-XXXXXX',
    dataLayerName: 'dataLayer',
    onBeforeInit: (client) => {
      // Set consent defaults for EU
      client.setConsentDefaults(consentPresets.eeaDefault, { region: ['EEA'] });
    }
  });
});

Available Composables

All composables from @jwiedeman/gtm-kit-vue are available:

useGtm()

<script setup>
import { useGtm } from '@jwiedeman/gtm-kit-vue';

const { push, updateConsent } = useGtm();
</script>

useGtmPush()

<script setup>
import { useGtmPush } from '@jwiedeman/gtm-kit-vue';

const push = useGtmPush();

push({ event: 'purchase', value: 99.99 });
</script>

useGtmConsent()

<script setup>
import { useGtmConsent } from '@jwiedeman/gtm-kit-vue';

const { updateConsent } = useGtmConsent();
</script>

Automatic Page Tracking

The Nuxt module automatically tracks page views on route changes. No additional setup required.

If you need custom page tracking:

<script setup>
import { useGtm } from '@jwiedeman/gtm-kit-vue';
import { useRoute } from 'vue-router';
import { watch } from 'vue';

const route = useRoute();
const { push } = useGtm();

// Custom page tracking with additional data
watch(
  () => route.fullPath,
  (path) => {
    push({
      event: 'page_view',
      page_path: path,
      page_title: document.title,
      user_type: 'logged_in' // custom data
    });
  }
);
</script>

Consent Mode v2 (GDPR)

// plugins/gtm.client.ts
import { GtmPlugin } from '@jwiedeman/gtm-kit-nuxt';
import { consentPresets } from '@jwiedeman/gtm-kit';

export default defineNuxtPlugin((nuxtApp) => {
  nuxtApp.vueApp.use(GtmPlugin, {
    containers: 'GTM-XXXXXX',
    onBeforeInit: (client) => {
      // Deny all by default for EU users
      client.setConsentDefaults(consentPresets.eeaDefault, { region: ['EEA'] });
    }
  });
});
<!-- components/CookieBanner.vue -->
<script setup>
import { useGtmConsent } from '@jwiedeman/gtm-kit-vue';
import { consentPresets } from '@jwiedeman/gtm-kit';

const { updateConsent } = useGtmConsent();

// Accept all tracking
const acceptAll = () => updateConsent(consentPresets.allGranted);

// Reject all tracking
const rejectAll = () => updateConsent(consentPresets.eeaDefault);

// Analytics only (mixed consent)
const analyticsOnly = () => updateConsent(consentPresets.analyticsOnly);

// Partial update - only change specific categories
const customChoice = () =>
  updateConsent({
    analytics_storage: 'granted',
    ad_storage: 'denied'
  });
</script>

<template>
  <div class="cookie-banner">
    <button @click="acceptAll">Accept All</button>
    <button @click="rejectAll">Reject All</button>
    <button @click="analyticsOnly">Analytics Only</button>
  </div>
</template>

Granular Updates - Update individual categories without affecting others:

<script setup>
const { updateConsent } = useGtmConsent();

// User later opts into ads from settings page
const enableAds = () =>
  updateConsent({
    ad_storage: 'granted',
    ad_user_data: 'granted'
  });
// analytics_storage and ad_personalization remain unchanged
</script>

SSR Considerations

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.

For noscript fallback (SEO), you can add this to your app.vue:

<template>
  <NuxtLayout>
    <NuxtPage />
  </NuxtLayout>

  <!-- GTM noscript fallback -->
  <noscript>
    <iframe
      src="https://www.googletagmanager.com/ns.html?id=GTM-XXXXXX"
      height="0"
      width="0"
      style="display:none;visibility:hidden"
    ></iframe>
  </noscript>
</template>

Multiple Containers

// plugins/gtm.client.ts
export default defineNuxtPlugin((nuxtApp) => {
  nuxtApp.vueApp.use(GtmPlugin, {
    containers: [{ id: 'GTM-MAIN' }, { id: 'GTM-ADS', queryParams: { gtm_auth: 'abc', gtm_preview: 'env-1' } }]
  });
});

Runtime Config

You can use Nuxt runtime config for the GTM ID:

// nuxt.config.ts
export default defineNuxtConfig({
  runtimeConfig: {
    public: {
      gtmId: process.env.GTM_ID || 'GTM-XXXXXX'
    }
  }
});
// plugins/gtm.client.ts
export default defineNuxtPlugin((nuxtApp) => {
  const config = useRuntimeConfig();

  nuxtApp.vueApp.use(GtmPlugin, {
    containers: config.public.gtmId
  });
});

Requirements

  • Nuxt 3.0+
  • Vue 3.3+
  • @jwiedeman/gtm-kit (peer dependency)

Related Packages


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