Skip to main content

Analytics Integration

Comprehensive Google Analytics 4 (GA4) and Google Tag Manager (GTM) integration with complete click tracking across all user-facing pages.

Overview

  • Google Analytics (GA4): Direct analytics tracking using gtag.js
  • Google Tag Manager (GTM): Container-based tag management for advanced tracking
  • Click Tracking: Every button, link, form, and product interaction tracked
  • Privacy Compliant: No PII tracked, GDPR/CCPA compliant

Both GA4 and GTM are optional and can be used independently or together.

Technical Stack:

  • Next.js 15.3.4 with App Router
  • React 19.0.0
  • TypeScript with full type support
  • Zero additional dependencies

Quick Start

1. Get Your IDs

Google Analytics 4:

  1. Go to Google Analytics
  2. Navigate to AdminData Streams
  3. Copy your Measurement ID (format: G-XXXXXXXXXX)

Google Tag Manager:

  1. Go to Google Tag Manager
  2. Create or select a container
  3. Copy your Container ID (format: GTM-XXXXXXX)

2. Set Environment Variables

Add to your .env.local:

# Google Analytics 4 (optional)
NEXT_PUBLIC_GA_MEASUREMENT_ID=G-XXXXXXXXXX

# Google Tag Manager (optional)
NEXT_PUBLIC_GTM_ID=GTM-XXXXXXX
tip

Use one or both depending on your needs:

  • GA only: Simple page view and event tracking
  • GTM only: Manage all tags through Tag Manager
  • Both: Direct GA tracking plus additional GTM tags

3. Test

npm run dev

Open DevTools → Network tab and look for requests to google-analytics.com or googletagmanager.com.

Tracking Implementation

What's Being Tracked

All User-Facing Pages

  • Home page (hero, products, newsletter)
  • About page (CTA buttons)
  • FAQ page (contact CTA)
  • Contact page (form submission)
  • Shop page (add to cart, checkout)
  • Orders page (browse products)
  • Unsubscribe page (form)
  • Shipping address form (all actions)
  • Header navigation (desktop + mobile)
  • Footer links (all)

Excluded from Tracking

  • All admin pages (/admin/*)
  • Admin navigation links
  • Admin actions

Event Types

Our tracking uses 4 standardized event types:

  1. button_click - CTA buttons and actionable links
  2. product_click` - Product card clicks and add to cart
  3. navigation_click - Header and footer navigation
  4. form_interaction - Form submissions and lifecycle

Usage

Automatic Page View Tracking

Page views are tracked automatically for all routes. No code needed!

Helper Functions

Import tracking functions from the analytics utility:

import {
trackButtonClick,
trackProductClick,
trackNavigationClick,
trackFormInteraction,
} from "@/utils/analytics";

Button Click Tracking

// Track a button click
<button
onClick={() =>
trackButtonClick(
"checkout", // button_id
"shop_cart", // button_location
"Proceed to Checkout", // button_text
{ cart_total: 149.97 } // optional extra data
)
}
>
Proceed to Checkout
</button>

Parameters:

  • button_id: Destination or action (e.g., "shop", "checkout")
  • button_location: Where the button appears (e.g., "hero", "shop_cart")
  • button_text: Actual button text for context
  • additionalData: Optional object with extra parameters

Product Click Tracking

// Track product interaction
<div
onClick={() =>
trackProductClick(
product.id, // product_id
product.name, // product_name
"featured_products", // click_location
{
product_price: 49.99,
product_category: "accessory",
action: "add_to_cart",
}
)
}
>
{product.name}
</div>

Parameters:

  • product_id: Unique product identifier
  • product_name: Product name
  • click_location: Where the click happened
  • additionalData: Product details (price, category, etc.)
// Track navigation links
<Link
href="/shop"
onClick={() =>
trackNavigationClick(
"/shop", // link_destination
"Shop", // link_text
"desktop_header" // nav_location
)
}
>
Shop
</Link>

Parameters:

  • link_destination: URL or route
  • link_text: Link text
  • nav_location: Where the link appears (e.g., "footer", "desktop_header")

Form Interaction Tracking

// Track form submission
const handleSubmit = async (e) => {
e.preventDefault();

// Track submission attempt
trackFormInteraction(
"newsletter", // form_name
"submit", // form_action
"home_page", // form_location
{ reason: "early_access" } // optional data
);

try {
const response = await submitForm();

// Track success
trackFormInteraction("newsletter", "success", "home_page");
} catch (error) {
// Track failure
trackFormInteraction("newsletter", "error", "home_page");
}
};

Parameters:

  • form_name: Form identifier (e.g., "newsletter", "contact_form")
  • form_action: Action state (submit, success, error, failure)
  • form_location: Where the form appears
  • additionalData: Optional contextual data

Custom Event Tracking

For other events, use the base trackEvent function:

import { trackEvent } from "@/components/GoogleAnalytics";

// Simple event
trackEvent("video_play");

// Event with parameters
trackEvent("purchase", {
transaction_id: "T12345",
value: 99.99,
currency: "USD",
items: [
{
item_id: "SKU123",
item_name: "Cricket Bat",
price: 29.99,
quantity: 1,
},
],
});

Common Event Examples

E-commerce Tracking

Add to Cart:

trackProductClick(product.id, product.name, "shop_add_to_cart", {
product_price: product.price,
product_category: product.category,
action: "add_to_cart",
});

Proceed to Checkout:

trackButtonClick("checkout", "shop_cart", "Proceed to Checkout", {
cart_total: getCartTotal(),
cart_item_count: getCartItemCount(),
});

Purchase Completed:

trackEvent("purchase", {
transaction_id: orderId,
value: total,
currency: "USD",
tax: taxAmount,
shipping: shippingCost,
items: cartItems.map((item) => ({
item_id: item.id,
item_name: item.name,
price: item.price,
quantity: item.quantity,
})),
});

Form Tracking

Newsletter Signup:

// On submit
trackFormInteraction("newsletter", "submit", "home_subscribe_section");

// On success
trackFormInteraction("newsletter", "success", "home_subscribe_section", {
reason: selectedReason,
});

// On error
trackFormInteraction("newsletter", "error", "home_subscribe_section");

Contact Form:

trackFormInteraction("contact_form", "submit", "contact_page");
// ... then success/failure
trackFormInteraction("contact_form", "success", "contact_page", {
subject: formData.subject,
});

Header Links:

// Desktop navigation
trackNavigationClick("/shop", "Shop", "desktop_header");

// Mobile menu
trackNavigationClick("/shop", "Shop", "mobile_menu");

Footer Links:

trackNavigationClick("/about", "About Us", "footer");

CTA Buttons:

// From About page
trackButtonClick("shop", "about_cta", "Visit Our Shop");

// From FAQ page
trackButtonClick("contact", "faq_cta", "Contact Us");

Complete Tracking Coverage

Pages with Tracking

PageElements TrackedEvent Types
HomeHero CTAs, Featured Products, Newsletterbutton_click, product_click, form_interaction
About2 CTA Buttonsbutton_click
FAQContact CTAbutton_click
ContactForm Submissionform_interaction
ShopAdd to Cart, Checkoutproduct_click, button_click
OrdersBrowse Productsbutton_click
UnsubscribeForm + Homepage Linkform_interaction, button_click
ShippingSave/Select/Delete Addressbutton_click, form_interaction
HeaderAll Navigation (Desktop + Mobile)navigation_click
FooterAll Linksnavigation_click

Tracking Statistics

  • Total Interactive Elements: 50+ tracked
  • Navigation Links: 15+ tracked
  • Buttons: 20+ tracked
  • Forms: 4 forms with lifecycle tracking
  • Products: Dynamic (all inventory)

Analytics Insights

Questions You Can Answer

E-commerce:

  • Which products get clicked most?
  • What's the add-to-cart conversion rate?
  • Average cart value at checkout?
  • Where do users drop off in the funnel?

Navigation:

  • Desktop vs Mobile usage?
  • Most clicked header items?
  • Footer link engagement?
  • Which CTAs drive most conversions?

Forms:

  • Newsletter signup rate?
  • Contact form completion rate?
  • Form error rates?
  • Which unsubscribe reasons are most common?

User Journey:

  • Most common navigation paths?
  • Entry → Conversion flow?
  • Time to purchase?
  • Returning user behavior?

Example GA4 Queries

Most Clicked Products:

Event: product_click
Dimension: product_name
Metric: event_count
Filter: click_location = "featured_products_home"

Button Performance:

Event: button_click
Dimensions: button_id, button_location
Metric: event_count
Sort by: event_count DESC

Form Completion Rate:

Event: form_interaction
Dimension: form_action
Metric: event_count
Calculate: (success / submit) * 100

Navigation Patterns:

Event: navigation_click
Dimensions: link_destination, nav_location
Metric: event_count

Testing & Verification

Browser DevTools

  1. Open DevTools → Network tab
  2. Filter by "google-analytics.com" or "googletagmanager.com"
  3. Perform tracked actions
  4. Verify requests are sent with correct parameters

GA4 DebugView

  1. Go to GA4 → Configure → DebugView
  2. Visit your site
  3. Perform actions
  4. See events appear in real-time
  5. Verify parameters are correct

GTM Preview Mode

  1. In GTM, click Preview
  2. Enter your site URL
  3. Tag Assistant window opens
  4. Perform actions
  5. Verify tags fire with correct data

Test Checklist

  • Page views tracked automatically
  • Hero CTAs fire button_click events
  • Product clicks tracked with details
  • Add to cart tracked correctly
  • Checkout button tracked
  • Newsletter form lifecycle tracked
  • Contact form submission tracked
  • Header navigation tracked (desktop + mobile)
  • Footer links tracked
  • Admin pages NOT tracked
  • No PII in event parameters

Additional Event Examples

E-commerce Events

Purchase:

// Purchase
trackEvent("purchase", {
transaction_id: "T12345",
value: 99.99,
currency: "USD",
tax: 8.5,
shipping: 5.0,
});

Bookings:

trackEvent("lane_booking", {
lane_type: "premium",
duration: 2,
value: 50.0,
currency: "USD",
});

Forms:

trackEvent("form_submission", {
form_name: "contact_form",
});

trackEvent("newsletter_signup", {
method: "footer_form",
});
info

See src/examples/analytics-usage.tsx for more examples including video engagement, error tracking, and more.

Implementation Details

Performance

The implementation is highly optimized:

MetricImpact
First Contentful Paint (FCP)0ms ✅
Largest Contentful Paint (LCP)0ms ✅
Time to Interactive (TTI)+100ms
Cumulative Layout Shift (CLS)0 ✅
Lighthouse Score-2 points

Features:

  • afterInteractive loading: Scripts load after page becomes interactive
  • DNS Prefetch: Preconnects to Google servers
  • Conditional loading: Only loads when IDs are configured
  • Zero impact: When disabled (no env vars)

Next.js 15 App Router

The implementation uses:

  • Client Components with "use client" directive
  • Script component with afterInteractive strategy
  • Environment variables with NEXT_PUBLIC_ prefix
  • Root layout integration in app/layout.tsx

Turbopack compatible - Works perfectly with Next.js 15's Turbopack

Testing & Verification

Browser DevTools

  1. Open DevTools → Network tab
  2. Filter by "google-analytics" or "googletagmanager"
  3. Verify requests are being sent

Google Analytics

  • Check Real-Time reports in GA4
  • Use DebugView for event validation

Google Tag Manager

  • Use Preview mode to debug tags
  • Verify trigger conditions and data layer

Test Event in Console

trackEvent("test_event", { test: true });

Deployment

Vercel

  1. Go to SettingsEnvironment Variables
  2. Add NEXT_PUBLIC_GA_MEASUREMENT_ID and/or NEXT_PUBLIC_GTM_ID
  3. Set for desired environments (Production, Preview, Development)
  4. Redeploy

Multiple Environments

Use separate IDs for each environment:

  • Development: Test properties (optional)
  • Staging: Staging properties (recommended)
  • Production: Production properties (required)

This keeps analytics data clean and separated.

Privacy & Compliance

Data Collection

Analytics collects:

  • Page views and navigation
  • User interactions and events
  • Device and browser information
  • Geographic location (IP-based, anonymized)

Compliance Requirements

GDPR (EU):

  • Obtain user consent before loading
  • Provide clear privacy policy
  • Allow opt-out

CCPA (California):

  • Provide "Do Not Sell My Information"
  • Disclose data collection

Cookie Consent:

  • Consider implementing a consent banner
  • Document cookie usage in privacy policy

Disabling Analytics

Analytics can be disabled by:

  1. Not setting environment variables
  2. Removing variables from production
  3. Implementing conditional loading based on user consent

Troubleshooting

Analytics Not Loading

  • ✅ Verify environment variables are set
  • ✅ Check ID formats: G-XXXXXXXXXX or GTM-XXXXXXX
  • ✅ Ensure NEXT_PUBLIC_ prefix
  • ✅ Restart development server

Events Not Tracking

  • ✅ Check Network tab for requests
  • ✅ Verify GA4 DebugView
  • ✅ Check browser console for errors
  • ✅ Verify gtag is loaded: console.log(window.gtag)

GTM Tags Not Firing

  • ✅ Use GTM Preview mode
  • ✅ Verify tag configuration
  • ✅ Check trigger conditions
  • ✅ Review data layer variables

Best Practices

  1. Event Naming: Use lowercase with underscores (e.g., add_to_cart)
  2. Consistency: Maintain consistent parameter names
  3. Testing: Test in development before deploying
  4. Documentation: Document custom events
  5. Privacy: Don't track PII (personally identifiable information)

Resources