Google Analytics Module for Nuxt.js applications providing Universal Analytics integration
npx @tessl/cli install tessl/npm-nuxtjs--google-analytics@2.4.0@nuxtjs/google-analytics is a Nuxt.js module that integrates Google Analytics (GA3/Universal Analytics) into Nuxt 2 applications using the vue-analytics library. It provides automatic page tracking, event tracking, and comprehensive analytics features through a simple configuration interface.
⚠️ Important: This module only supports GA3/Universal Analytics and is not compatible with GA4. For Nuxt 3 applications, use nuxt-gtag instead.
npm install @nuxtjs/google-analyticsThis module is registered as a Nuxt module, not imported directly:
// nuxt.config.js
export default {
buildModules: [
'@nuxtjs/google-analytics' // Nuxt 2.9+
],
// OR for older versions:
modules: [
'@nuxtjs/google-analytics'
]
}// nuxt.config.js
export default {
buildModules: [
'@nuxtjs/google-analytics'
],
googleAnalytics: {
id: 'UA-12301-2' // Your Google Analytics tracking ID
}
}Access the analytics instance in your components:
export default {
mounted() {
// Track an event
this.$ga.event('button', 'click', 'nav buttons', 1)
// Track a page view
this.$ga.page('/my-page')
}
}@nuxtjs/google-analytics is built around a simple yet effective modular architecture:
Module Layer (module.js): Nuxt module that processes configuration options, handles development mode behavior, and registers the client-side plugin. Merges module options with runtime config and ensures backward compatibility.
Plugin Layer (plugin.js): Client-side plugin that initializes vue-analytics with the router instance and injects the $ga instance into the Nuxt context. Handles async ID resolution and runtime configuration merging.
Integration Layer: TypeScript definitions that augment Nuxt's context, Vue instances, and Vuex store with the $ga property, providing type safety across the application.
Analytics Engine: The underlying vue-analytics library that provides the actual Google Analytics functionality, including automatic page tracking, event batching, and comprehensive GA feature support.
The data flow follows this pattern:
$ga instance becomes available throughout the applicationThe main Nuxt module function that configures and registers the Google Analytics plugin.
/**
* Main module function - automatically called by Nuxt
* @param moduleOptions - Module configuration options
*/
function analyticsModule(moduleOptions: ModuleOptions): void;Configuration options for the Google Analytics module.
interface ModuleOptions {
/** Google Analytics tracking ID (required) */
id: string;
/** Async function that returns the tracking ID */
asyncID?: (context: Context) => Promise<string>;
/** Enable module in development mode (default: true) */
dev?: boolean;
/** Debug configuration */
debug?: {
/** Enable debug mode */
enabled?: boolean;
/** Send hits to GA (default: undefined in dev mode, true in production) */
sendHitTask?: boolean;
};
/** Detect duplicate analytics scripts */
checkDuplicatedScript?: boolean;
/** Disable automatic script loading */
disableScriptLoader?: boolean;
/** Legacy alias for id (deprecated) */
ua?: string;
/** All vue-analytics options are also supported */
[key: string]: any;
}The module injects the $ga instance into the Nuxt context, making it available throughout your application.
interface NuxtContext {
/** Vue Analytics instance for tracking */
$ga: VueAnalytics;
}
interface Vue {
/** Vue Analytics instance for tracking */
$ga: VueAnalytics;
}
interface Store<S> {
/** Vue Analytics instance for tracking in Vuex store */
$ga: VueAnalytics;
}The client-side plugin that initializes vue-analytics and provides the tracking functionality.
/**
* Plugin function that sets up Vue Analytics
* Automatically called by Nuxt on client-side
*/
async function plugin(context: Context, inject: Function): Promise<void>;Multiple ways to configure the module:
// In nuxt.config.js
export default {
googleAnalytics: {
id: 'UA-XXX-X'
},
// Runtime configuration support
publicRuntimeConfig: {
googleAnalytics: {
id: process.env.GA_ID
}
}
}Support for dynamically resolving the tracking ID at runtime:
interface AsyncIDFunction {
(context: Context): Promise<string>;
}
// Usage example:
const config = {
googleAnalytics: {
asyncID: async (context) => {
// Resolve ID based on context
return context.route.params.siteId
? `UA-${context.route.params.siteId}-1`
: 'UA-DEFAULT-1';
}
}
}declare module '@nuxt/vue-app' {
interface Context {
$ga: VueAnalytics;
}
interface NuxtAppOptions {
$ga: VueAnalytics;
}
}
declare module '@nuxt/types' {
interface Context {
$ga: VueAnalytics;
}
interface NuxtAppOptions {
$ga: VueAnalytics;
}
interface Configuration {
googleAnalytics?: InstallOptions;
}
}
declare module 'vue/types/vue' {
interface Vue {
$ga: VueAnalytics;
}
}
declare module 'vuex' {
interface Store<S> {
$ga: VueAnalytics;
}
}The $ga instance provides the full vue-analytics API with comprehensive Google Analytics functionality:
interface VueAnalytics {
/** Track a page view with flexible parameter support */
page(path: string | object): void;
page(route: Route): void;
page(path: string, title: string, location?: string): void;
/** Track an event with flexible parameters */
event(category: string, action: string, label?: string, value?: number): void;
event(eventObject: {
eventCategory: string;
eventAction: string;
eventLabel?: string;
eventValue?: number;
[key: string]: any;
}): void;
/** Track screen views for mobile/SPA applications */
screenview(screenName: string): void;
screenview(screenObject: {
screenName: string;
appName?: string;
appVersion?: string;
[key: string]: any;
}): void;
/** Track user timing for performance metrics */
time(category: string, variable: string, value: number, label?: string): void;
time(timingObject: {
timingCategory: string;
timingVar: string;
timingValue: number;
timingLabel?: string;
[key: string]: any;
}): void;
/** Track social interactions */
social(network: string, action: string, target: string): void;
social(socialObject: {
socialNetwork: string;
socialAction: string;
socialTarget: string;
[key: string]: any;
}): void;
/** Track exceptions and errors */
exception(description: string, fatal?: boolean): void;
exception(exceptionObject: {
exDescription: string;
exFatal?: boolean;
[key: string]: any;
}): void;
/** Set custom dimensions, metrics, and configuration */
set(field: string, value: any): void;
set(fieldsObject: { [field: string]: any }): void;
/** Require and configure GA plugins */
require(pluginName: string, pluginOptions?: object): void;
/** Send custom hit to Google Analytics */
send(hitType: string, params: object): void;
/** Core query method for direct GA commands */
query(...args: any[]): void;
/** Enhanced e-commerce tracking */
ecommerce: {
/** Add e-commerce item (classic e-commerce) */
addItem(itemData: {
id: string;
name?: string;
category?: string;
sku?: string;
price?: number;
quantity?: number;
}): void;
/** Add e-commerce transaction (classic e-commerce) */
addTransaction(transactionData: {
id: string;
affiliation?: string;
revenue?: number;
shipping?: number;
tax?: number;
}): void;
/** Add enhanced e-commerce product */
addProduct(productData: {
id: string;
name?: string;
category?: string;
brand?: string;
variant?: string;
price?: number;
quantity?: number;
coupon?: string;
position?: number;
}): void;
/** Add product impression for enhanced e-commerce */
addImpression(impressionData: {
id: string;
name?: string;
category?: string;
brand?: string;
variant?: string;
list?: string;
position?: number;
price?: number;
}): void;
/** Set e-commerce action for enhanced e-commerce */
setAction(action: string, actionData?: {
id?: string;
affiliation?: string;
revenue?: number;
tax?: number;
shipping?: number;
coupon?: string;
list?: string;
step?: number;
option?: string;
}): void;
/** Add promotional data for enhanced e-commerce */
addPromo(promoData: {
id: string;
name?: string;
creative?: string;
position?: string;
}): void;
/** Send e-commerce data to Google Analytics */
send(): void;
/** Clear e-commerce data */
clear(): void;
};
}// Basic event tracking
this.$ga.event('button', 'click', 'navbar', 1)
// Object-based event tracking
this.$ga.event({
eventCategory: 'user',
eventAction: 'login',
eventLabel: 'social-media',
customDimension1: 'facebook'
})// Simple path tracking
this.$ga.page('/about')
// Router-based tracking (automatic)
this.$ga.page(this.$route)
// Custom page with title
this.$ga.page('/products', 'Product Catalog')
// Object-based page tracking
this.$ga.page({
page: '/special-page',
title: 'Special Page Title',
location: 'https://example.com/special-page'
})// Add product to cart
this.$ga.ecommerce.addProduct({
id: 'SKU123',
name: 'Product Name',
category: 'Category',
brand: 'Brand',
variant: 'Color',
price: 15.99,
quantity: 1
})
// Purchase action
this.$ga.ecommerce.setAction('purchase', {
id: 'T12345',
affiliation: 'Online Store',
revenue: 35.43,
tax: 4.90,
shipping: 5.99,
coupon: 'SUMMER2023'
})
// Send e-commerce data
this.$ga.ecommerce.send()// Set user properties
this.$ga.set('userId', 'user123')
this.$ga.set('customDimension1', 'premium-user')
// Bulk configuration
this.$ga.set({
userId: 'user123',
customDimension1: 'premium-user',
customDimension2: 'mobile-app',
customMetric1: 42
})// Track loading time
this.$ga.time('page', 'load', 3400, 'home-page')
// Object-based timing
this.$ga.time({
timingCategory: 'api',
timingVar: 'response',
timingValue: 245,
timingLabel: 'user-data'
})// Track non-fatal exception
this.$ga.exception('API timeout', false)
// Track fatal exception
this.$ga.exception({
exDescription: 'Database connection failed',
exFatal: true,
customDimension3: 'production'
})// Mobile/SPA screen tracking
this.$ga.screenview('Home Screen')
// Detailed screen view
this.$ga.screenview({
screenName: 'Product Detail',
appName: 'MyApp',
appVersion: '1.2.0'
})// Track social shares
this.$ga.social('facebook', 'share', '/article/123')
// Object-based social tracking
this.$ga.social({
socialNetwork: 'twitter',
socialAction: 'tweet',
socialTarget: '/blog/analytics-guide'
})// Load enhanced e-commerce plugin
this.$ga.require('ec')
// Load display features
this.$ga.require('displayfeatures')
// Custom hit
this.$ga.send('event', {
eventCategory: 'custom',
eventAction: 'api-call',
nonInteraction: true
})The module provides access to all vue-analytics features:
The module automatically injects $ga into the Vuex store, enabling analytics tracking from actions and mutations:
// In store actions
export const actions = {
async login({ commit }, userData) {
// Track login attempt
this.$ga.event('user', 'login-attempt', userData.provider)
try {
const result = await this.$axios.post('/auth/login', userData)
commit('SET_USER', result.data)
// Track successful login
this.$ga.event('user', 'login-success', userData.provider)
this.$ga.set('userId', result.data.id)
} catch (error) {
// Track login failure
this.$ga.exception('Login failed: ' + error.message, false)
}
}
}Support for multiple Google Analytics properties:
// nuxt.config.js
export default {
googleAnalytics: {
id: ['UA-XXXXX-1', 'UA-XXXXX-2'], // Multiple tracking IDs
// Configure trackers separately if needed
trackers: {
'UA-XXXXX-1': { name: 'primary' },
'UA-XXXXX-2': { name: 'secondary', debug: true }
}
}
}Load additional Google Analytics plugins:
// In a component or plugin
mounted() {
// Load enhanced e-commerce
this.$ga.require('ec')
// Load display features for demographics
this.$ga.require('displayfeatures')
// Load enhanced link attribution
this.$ga.require('linkid')
// Custom plugin with configuration
this.$ga.require('customPlugin', {
customParam: 'value'
})
}Configure cross-domain tracking for multiple domains:
// nuxt.config.js
export default {
googleAnalytics: {
id: 'UA-XXXXX-1',
crossDomain: {
domains: ['example.com', 'shop.example.com'],
allowLinker: true
}
}
}Dynamically resolve tracking IDs based on runtime context:
// nuxt.config.js
export default {
googleAnalytics: {
asyncID: async (context) => {
// Get ID from API or based on route
if (context.route.params.tenant) {
const config = await context.$axios.$get(`/config/${context.route.params.tenant}`)
return config.gaTrackingId
}
return process.env.DEFAULT_GA_ID
}
}
}Set up content grouping and custom dimensions:
// In layouts or pages
mounted() {
// Set content group
this.$ga.set('contentGroup1', 'Blog Posts')
this.$ga.set('contentGroup2', 'Technology')
// Set custom dimensions
this.$ga.set('customDimension1', 'logged-in-user')
this.$ga.set('customDimension2', this.$auth.user?.subscription_type)
// Track page with content grouping
this.$ga.page(this.$route.path)
}Complete e-commerce tracking implementation:
// Product list view
methods: {
trackProductListView() {
this.products.forEach((product, index) => {
this.$ga.ecommerce.addImpression({
id: product.sku,
name: product.name,
category: product.category,
brand: product.brand,
list: 'Search Results',
position: index + 1
})
})
this.$ga.ecommerce.send()
},
trackProductClick(product, position) {
this.$ga.ecommerce.addProduct({
id: product.sku,
name: product.name,
category: product.category,
position: position
})
this.$ga.ecommerce.setAction('click', { list: 'Search Results' })
this.$ga.ecommerce.send()
}
}Track application performance metrics:
// In plugins or middleware
export default function({ $ga, route }) {
// Track page load timing
window.addEventListener('load', () => {
const navigation = performance.getEntriesByType('navigation')[0]
$ga.time('page', 'load', Math.round(navigation.loadEventEnd), route.path)
})
// Track API response times
const originalFetch = window.fetch
window.fetch = async (...args) => {
const start = performance.now()
try {
const response = await originalFetch(...args)
const duration = Math.round(performance.now() - start)
$ga.time('api', 'response', duration, args[0])
return response
} catch (error) {
$ga.exception(`API Error: ${args[0]}`, false)
throw error
}
}
}In development mode (when this.options.dev is true):
dev: true is explicitly set in module optionsdebug.sendHitTask set to false if undefined)ua option to id automaticallygoogleAnalytics and google-analytics configuration keysThe module gracefully handles:
checkDuplicatedScript option)nuxt-gtag insteadua option: Automatically converted to id, but prefer using id directlyThis module provides access to the complete vue-analytics API. For comprehensive documentation of all analytics methods and advanced configuration options, see:
Note: vue-analytics is no longer actively maintained. For new projects, consider migrating to vue-gtag or nuxt-gtag for better long-term support.