gtag
nuxt-gtag

Google Analytics integration: Google Analytics, Google Ads and more

Nuxt Google Tag module

Nuxt Google Tag

Google Analytics, Google Ads and Consent Mode v2 for Nuxt, through Google's own gtag.js.

Features

  • 🌻 Loads no tracking library of its own, only Google's gtag.js
  • 🛍️ Use Google Analytics 4, Google Ads and other products
  • 🛎️ Supports Google Consent Mode v2
  • 🤝 Manually initialize a Google tag
  • 🔢 Supports multiple tag IDs
  • 📯 Track events with composables
  • 🏷️ Fully typed gtag.js API
  • 🦾 SSR-ready

Setup

Install nuxt-gtag and add it to the modules section of your Nuxt configuration in one step:

npx nuxt module add gtag

Basic Usage

Provide your Google tag ID under the gtag key of your Nuxt configuration. For more than one, see Add Multiple Google Tags.

// `nuxt.config.ts`
export default defineNuxtConfig({
  modules: ['nuxt-gtag'],

  gtag: {
    id: 'G-XXXXXXXXXX'
  }
})

Done! The module loads the gtag.js script client-side and initializes it with your Google tag ID when the Nuxt application starts.

gtag.js tracks page changes in Nuxt through GA4's Enhanced measurement. In the settings of your web data stream, make sure "Page changes based on browser history events" is enabled.

Configuration

Set the module options under the gtag key of your Nuxt configuration:

export default defineNuxtConfig({
  modules: ['nuxt-gtag'],

  gtag: {
    id: 'G-XXXXXXXXXX',
    config: {
      page_title: 'My Custom Page Title'
    }
  }
})

Enable the Module per Environment

Set the enabled option to false to disable the module in an environment such as development or staging:

export default defineNuxtConfig({
  modules: ['nuxt-gtag'],

  gtag: {
    enabled: process.env.NODE_ENV === 'production',
    id: 'G-XXXXXXXXXX'
  }
})

While the module is disabled, useGtag and useTrackEvent stay auto-imported as no-ops, so the calls in your code need no guard.

Unlike the tag ID, enabled cannot be overridden by an environment variable at runtime.

Add Multiple Google Tags

To send data to more than one destination, list the Google tag IDs in the tags option. Each entry is a tag ID string or an object with id and its own config and initCommands:

export default defineNuxtConfig({
  modules: ['nuxt-gtag'],

  gtag: {
    tags: [
      // Google Ads and GA4, with additional configuration
      {
        id: 'G-XXXXXXXXXX',
        config: {
          page_title: 'My Custom Page Title'
        }
      },
      // Second Google tag ID for Floodlight
      'DC-ZZZZZZZZZZ'
    ]
  }
})

The top-level config and initCommands do not apply to the entries of tags.

Set the Tag ID From an Environment Variable

Instead of hard-coding your Google tag ID in your Nuxt configuration, set it in your project's .env file – Nuxt overwrites public runtime config values with matching environment variables at runtime.

# Overwrites the `gtag.id` module option
NUXT_PUBLIC_GTAG_ID=G-XXXXXXXXXX

With this setup, you can omit the gtag key in your Nuxt configuration if you only intend to set the Google tag ID.

Follows the Google Consent Mode v2 specification.

Set a default value for each consent type you use. Without initCommands, no consent mode values are set:

export default defineNuxtConfig({
  modules: ['nuxt-gtag'],

  gtag: {
    id: 'G-XXXXXXXXXX',
    initCommands: [
      // Set up consent mode
      [
        'consent',
        'default',
        {
          ad_user_data: 'denied',
          ad_personalization: 'denied',
          ad_storage: 'denied',
          analytics_storage: 'denied',
          wait_for_update: 500,
        }
      ]
    ]
  }
})

A setup with tags and no id skips the top-level initCommands – set the defaults on a tags entry instead.

After a user indicates their consent choices, update the consent types they granted – all of them, or a subset such as ad_storage alone:

const { gtag } = useGtag()

// Invoke when a user interacts with your banner
function allConsentGranted() {
  gtag('consent', 'update', {
    ad_user_data: 'granted',
    ad_personalization: 'granted',
    ad_storage: 'granted',
    analytics_storage: 'granted'
  })
}

Load the gtag.js Script Manually

For even more control than the consent mode, you can delay the loading of the gtag.js script until the user has granted consent to your privacy policy. Set the initMode option to manual to hold back the gtag.js script and every command, initCommands included, until you initialize it manually.

export default defineNuxtConfig({
  modules: ['nuxt-gtag'],

  gtag: {
    initMode: 'manual',
    id: 'G-XXXXXXXXXX'
  }
})

Then call initialize from useGtag, for example when the user accepts your privacy policy:

<script setup lang="ts">
const { initialize } = useGtag()
</script>

<template>
  <button @click="initialize()">
    Grant Consent
  </button>
</template>

Set the Tag ID per Tenant

Leave the Google tag ID in your Nuxt configuration blank and pass it to initialize as the first argument instead. Reach for this when each user or tenant brings their own ID.

const { initialize } = useGtag()

function acceptTracking() {
  initialize('G-TENANT-123')
  // Optionally, track the current page view
  // useTrackEvent('page_view')
}

Consent defaults do not need a static id either: set initCommands on their own, and they run before the tenant's ID is configured.

Module Options

OptionTypeDefaultDescription
enabledbooleantrueWhether to enable the Google tag module for the current environment.
initMode'auto' | 'manual''auto'Whether to initialize the Google tag script immediately after the page has loaded. Set it to 'manual' to initialize with initialize instead.
idstring''The Google tag ID to initialize.
initCommands[command, ...args][][]Commands to run before the tag ID is configured, such as the default consent state. Entries in tags carry their own.
configControlParams | EventParams | ConfigParams | CustomParams{}The configuration parameters passed to the config command. Entries in tags carry their own.
tags(string | GoogleTagOptions)[][]Further tags to initialize, for sending data to more than one destination.
loadingStrategy'async' | 'defer''defer'Whether the gtag.js script is loaded with async or with defer.
urlstring'https://www.googletagmanager.com/gtag/js'The URL to load the gtag.js script from.

Composables

Nuxt auto-imports both composables. Both are SSR-safe: on the server, their calls have no effect.

useGtag

const { gtag, initialize, disableAnalytics, enableAnalytics } = useGtag()

Type Declarations

function useGtag(): {
  gtag: Gtag
  initialize: (id?: string) => void
  disableAnalytics: (id?: string) => void
  enableAnalytics: (id?: string) => void
}

gtag

Runs any gtag.js command.

Example

const { gtag } = useGtag()

gtag('event', 'screen_view', {
  app_name: 'My App',
  screen_name: 'Home'
})

initialize

Injects the gtag.js script into the document's head and configures the tag IDs. gtag calls made before the first tag ID is configured are held and follow its config command. With a tag ID in the module options, it requires initMode: 'manual'.

The function accepts an optional ID for a Google tag that the module options do not carry. The ID joins the ones from your configuration rather than replacing them, so the call configures that tag and every tag still waiting.

A tag ID is configured once. Calling initialize again passes only the IDs it has not configured yet to the config command, so a consent flow may call it as often as it needs to.

Called without an ID while the module options hold no tag either, initialize logs [nuxt-gtag] Missing Google tag ID for initialize() to the console and does nothing. The likely cause is an empty NUXT_PUBLIC_GTAG_ID, or a per-tenant setup that calls initialize() without the tenant's ID.

disableAnalytics

Stops gtag.js from sending data to Google Analytics without removing the Google tag, for example when a user opts out of tracking.

The optional ID names the tag to switch off. It covers one tag, so a setup with multiple tag IDs needs one call per tag. Without an argument, only the first tag from the module options is affected.

The opt-out lasts until the next full page load. Store the user's choice and call disableAnalytics again on each load.

enableAnalytics

Re-enables Google Analytics after disableAnalytics has switched it off. The id parameter selects the tag the same way as in disableAnalytics.

useTrackEvent

Fires a recommended or custom event, optionally with parameters that describe it.

Example

useTrackEvent('login', {
  method: 'Google'
})

Type Declarations

function useTrackEvent(
  eventName: EventNames | (string & {}),
  eventParams?: ControlParams | EventParams | CustomParams
): void

💻 Development

  1. Clone this repository
  2. Enable Corepack using corepack enable
  3. Install dependencies using pnpm install
  4. Run pnpm run dev:prepare
  5. Start development server using pnpm run dev

Credits

License

MIT License © 2023-PRESENT Johann Schopplich