Analytics
Google Analytics, Google Tag Manager, Amplitude, and Vercel Analytics setup
Analytics
Jose Madrid Salsa uses four analytics systems, each serving a distinct purpose.
Analytics Stack Overview
| Tool | Purpose | Data Location |
|---|---|---|
| Google Tag Manager | Tag orchestration, event routing | GTM Dashboard |
| Google Analytics 4 | Traffic, conversions, SEO | GA4 Dashboard |
| Amplitude | Product analytics, user journeys, session replay | Amplitude Dashboard |
| Vercel Analytics | Web Vitals, performance metrics | Vercel Dashboard |
Google Tag Manager
GTM is loaded in the root layout (app/layout.tsx) with container ID GTM-NTWG6BQW using next/script with strategy="lazyOnload". A noscript fallback iframe is also included for non-JavaScript environments.
GTM manages:
- Google Analytics tags
- Conversion tracking pixels
- Custom event forwarding
Google Analytics 4
GA4 is loaded as a separate React component for flexibility:
export function GoogleAnalytics({ measurementId }: GoogleAnalyticsProps) {
const resolvedId =
measurementId || process.env.NEXT_PUBLIC_GOOGLE_ANALYTICS_ID || 'G-HG4QV5GFKH'
// Renders gtag.js script and config via next/script
}The measurement ID is resolved server-side via getPublicGoogleAnalyticsMeasurementId(), enabling dynamic configuration without code changes.
Environment Variables
GOOGLE_ANALYTICS_ID="G-HG4QV5GFKH" # GA4 measurement IDAmplitude
Amplitude provides deep product analytics with session replay.
Initialization
import * as amplitude from '@amplitude/unified'
export const initAmplitude = () => {
// Nothing starts until the visitor accepts the cookie banner; replay records page text.
if (localStorage.getItem('cookie-consent') !== 'accepted') return false
if (isInitialized) return true
const apiKey = process.env.NEXT_PUBLIC_AMPLITUDE_API_KEY
if (!apiKey) {
console.warn('Amplitude API key missing — analytics disabled')
return false
}
// Analytics with autocapture, plus session replay on every consented session.
amplitude.initAll(apiKey, { analytics: { autocapture: true }, sessionReplay: { sampleRate: 1 } })
isInitialized = true
return true
}
// Rejecting cookies later calls this; replay honours the same opt-out.
export const disableAmplitude = () => amplitude.setOptOut(true)Client Component
'use client'
import { useEffect } from 'react'
import { initAmplitude } from '@/lib/analytics/amplitude'
export function AmplitudeAnalytics() {
useEffect(() => {
initAmplitude()
}, [])
return null
}Tracking Custom Events
import { trackEvent, identifyUser, resetUser } from '@/lib/analytics/amplitude'
// Track a purchase
trackEvent('purchase_completed', {
orderId: order.id,
total: order.total,
itemCount: order.items.length,
})
// Identify a logged-in user
identifyUser(user.id, {
email: user.email,
role: user.role,
})
// Clear on logout
resetUser()Environment Variables
NEXT_PUBLIC_AMPLITUDE_API_KEY="..." # Amplitude project API keyVercel Analytics
Vercel Analytics is the simplest integration -- a single component:
import { Analytics } from '@vercel/analytics/react'
// At the end of the layout:
<Analytics />This automatically captures Core Web Vitals (LCP, FID, CLS, TTFB, INP) and page view data. No additional configuration is needed as Vercel detects the linked project automatically.
Loading Strategy
Analytics tags in the root layout use strategy="lazyOnload" from next/script, which loads them after the page's load event. This keeps their JavaScript out of the first render and off the main thread while the page hydrates (better LCP and Total Blocking Time). Events pushed before a tag arrives wait in its queue (dataLayer, fbq, ttq).
Page Load Timeline:
HTML parse + hydration
Amplitude SDK is fetched (dynamic import) if the visitor has accepted analytics cookies
Page load event
GTM loads (lazyOnload), then GA4 via GTM
Meta / TikTok pixels load (lazyOnload)
Vercel Analytics captures Web VitalsNo PostHog
PostHog is not currently integrated into the application. The analytics stack uses Amplitude for product analytics and session replay instead.
How is this guide?
Last updated on