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:
- Go to Google Analytics
- Navigate to Admin → Data Streams
- Copy your Measurement ID (format:
G-XXXXXXXXXX)
Google Tag Manager:
- Go to Google Tag Manager
- Create or select a container
- 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
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:
button_click- CTA buttons and actionable links- product_click` - Product card clicks and add to cart
navigation_click- Header and footer navigationform_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 contextadditionalData: 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 identifierproduct_name: Product nameclick_location: Where the click happenedadditionalData: Product details (price, category, etc.)
Navigation Click Tracking
// 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 routelink_text: Link textnav_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 appearsadditionalData: 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,
});
Navigation Tracking
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
| Page | Elements Tracked | Event Types |
|---|---|---|
| Home | Hero CTAs, Featured Products, Newsletter | button_click, product_click, form_interaction |
| About | 2 CTA Buttons | button_click |
| FAQ | Contact CTA | button_click |
| Contact | Form Submission | form_interaction |
| Shop | Add to Cart, Checkout | product_click, button_click |
| Orders | Browse Products | button_click |
| Unsubscribe | Form + Homepage Link | form_interaction, button_click |
| Shipping | Save/Select/Delete Address | button_click, form_interaction |
| Header | All Navigation (Desktop + Mobile) | navigation_click |
| Footer | All Links | navigation_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
- Open DevTools → Network tab
- Filter by "google-analytics.com" or "googletagmanager.com"
- Perform tracked actions
- Verify requests are sent with correct parameters
GA4 DebugView
- Go to GA4 → Configure → DebugView
- Visit your site
- Perform actions
- See events appear in real-time
- Verify parameters are correct
GTM Preview Mode
- In GTM, click Preview
- Enter your site URL
- Tag Assistant window opens
- Perform actions
- 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",
});
See src/examples/analytics-usage.tsx for more examples including video engagement, error tracking, and more.
Implementation Details
Performance
The implementation is highly optimized:
| Metric | Impact |
|---|---|
| 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:
afterInteractiveloading: 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
afterInteractivestrategy - 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
- Open DevTools → Network tab
- Filter by "google-analytics" or "googletagmanager"
- 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
- Go to Settings → Environment Variables
- Add
NEXT_PUBLIC_GA_MEASUREMENT_IDand/orNEXT_PUBLIC_GTM_ID - Set for desired environments (Production, Preview, Development)
- 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:
- Not setting environment variables
- Removing variables from production
- Implementing conditional loading based on user consent
Troubleshooting
Analytics Not Loading
- ✅ Verify environment variables are set
- ✅ Check ID formats:
G-XXXXXXXXXXorGTM-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
- Event Naming: Use lowercase with underscores (e.g.,
add_to_cart) - Consistency: Maintain consistent parameter names
- Testing: Test in development before deploying
- Documentation: Document custom events
- Privacy: Don't track PII (personally identifiable information)
Resources
- Google Analytics 4 Documentation
- Google Tag Manager Documentation
- Next.js Analytics Documentation
- Next.js Script Component
- Code examples:
src/examples/analytics-usage.tsx