The boilerplate includes consent-aware analytics integrations for tracking user behavior, conversions, and providing live customer support.

Google Tag Manager

Centralized tag management with consent mode.

Google Ads

Conversion tracking via gtag.js with dynamic values.

Meta Pixel

Facebook/Instagram conversion tracking.

Crisp Chat

Live chat with user identification.

Consent-Aware

GDPR-compliant cookie consent integration.

Google Tag Manager

Configure with NEXT_PUBLIC_GTM_ID for your GTM container (GTM-XXX). For GA4 and Google Ads, use the dedicated env vars (NEXT_PUBLIC_GA_MEASUREMENT_ID and NEXT_PUBLIC_GOOGLE_ADS_ID) which are handled by the GoogleAdsTag component.

Env Variable ID Format Script Loaded Component
NEXT_PUBLIC_GTM_ID GTM-XXXXXXX gtm.js GoogleTagManager
NEXT_PUBLIC_GA_MEASUREMENT_ID G-XXXXXXX gtag/js (primary) GoogleAdsTag
NEXT_PUBLIC_GOOGLE_ADS_ID AW-XXXXXXX gtag/js (secondary config) GoogleAdsTag
GTM + gtag.js Separation

GTM (gtm.js) and gtag.js are loaded by separate components and coexist via the shared window.dataLayer. To avoid double-counting conversions, do not configure Google Ads conversion tags in your GTM container — use gtag.js for conversions (via NEXT_PUBLIC_GOOGLE_ADS_CONVERSION_PURCHASE / NEXT_PUBLIC_GOOGLE_ADS_CONVERSION_SIGNUP). All IDs are validated against strict regex patterns to prevent XSS via env injection.

Feature Description
Consent Mode Integrates with the cookie consent banner. Analytics fires only after analytics consent, marketing/ad tags only after marketing consent, and Global Privacy Control keeps marketing consent disabled.
Page Views Automatic page view tracking on route changes
User Events Login, signup, and subscription events
E-commerce Purchase and checkout events for Stripe
Custom Events AI usage, chat sessions, and custom interactions

Google Ads Conversion Tracking

Track Google Ads conversions via gtag.js with per-action conversion tags. The gtag.js script is loaded with async + Next.js strategy="afterInteractive", deferring the request until after hydration to keep it off the critical path while remaining detectable by Google Tag Assistant.

Feature Description
Google-Compliant Loading gtag.js loaded with async + Next.js afterInteractive strategy — injected after hydration, still detected by Google Tag Assistant
Consent Mode v2 Defaults to denied, instantly restores prior consent from localStorage (no hydration wait for returning users)
Per-Action Conversion Tags NEXT_PUBLIC_GOOGLE_ADS_CONVERSION_PURCHASE (format: AW-XXX/LABEL) and NEXT_PUBLIC_GOOGLE_ADS_CONVERSION_SIGNUP — each event fires its own send_to
Auto-Fired: Purchase Fires on checkout success page via trackConversion() with real Stripe session data (amount, currency, transaction ID)
Auto-Fired: Signup Fires on onboarding completion via trackSignUp() — also triggers GTM sign_up + Meta Pixel CompleteRegistration
Pre-built Events googleAdsEvents.purchase(), .lead(), .signUp(), .creditPurchase(), .custom()
Click Tracking gtagReportConversion(url, params) — onClick handler that tracks conversion then redirects (with open-redirect protection)
Deduplication Uses transaction_id to prevent duplicate conversions on page refresh
Unified Methods trackConversion() and trackSignUp() via useAnalytics() hook fire Google Ads + GTM + Meta Pixel in one call
Security Env var format validation (prevents XSS), URL protocol validation, Stripe session_id format check

Usage Examples

// Via the unified analytics hook (recommended — respects consent)
const { trackConversion, trackSignUp } = useAnalytics()

// Purchase conversion (auto-fired on checkout success page)
trackConversion({
  transactionId: 'cs_live_xxx',
  value: 29.99,
  currency: 'EUR',
})

// Signup conversion (auto-fired on onboarding completion)
trackSignUp()

// Direct Google Ads conversion with specific send_to
import { googleAdsEvents } from '@/components/analytics'
googleAdsEvents.purchase('txn_123', 29.99, 'EUR')  // uses CONVERSION_PURCHASE
googleAdsEvents.signUp()                              // uses CONVERSION_SIGNUP
googleAdsEvents.lead(5.0)                             // uses CONVERSION_SIGNUP

// On button/link click with redirect
import { gtagReportConversion } from '@/components/analytics'
<button onClick={() => gtagReportConversion('/thank-you', { value: 29.99 })}>
  Buy Now
</button>
Avoiding Double-Counting

GTM (gtm.js) and gtag.js coexist via the shared window.dataLayer. To prevent double-counting, do not configure Google Ads conversion tags in your GTM container — conversions are tracked via gtag.js using the per-action env vars (NEXT_PUBLIC_GOOGLE_ADS_CONVERSION_PURCHASE, NEXT_PUBLIC_GOOGLE_ADS_CONVERSION_SIGNUP).

Meta Pixel (Facebook)

Track conversions for Facebook and Instagram ads. Configure with NEXT_PUBLIC_META_PIXEL_ID.

  • Loads only when marketing consent is granted
  • Tracks PageView on route changes
  • E-commerce events (Purchase, InitiateCheckout)
  • Lead events (CompleteRegistration, Subscribe)

X (Twitter) Pixel

Track conversions for X (Twitter) Ads campaigns via the universal website tag (uwt.js). Configure with NEXT_PUBLIC_X_PIXEL_ID (base pixel ID from X Ads Manager, e.g. o1abc) plus the per-action event IDs NEXT_PUBLIC_X_PIXEL_EVENT_PURCHASE and NEXT_PUBLIC_X_PIXEL_EVENT_SIGNUP (format: tw-XXXXX-XXXXX). Loaded by the XPixel component (components/analytics/x-pixel.tsx) and orchestrated by AnalyticsProvider.

Feature Description
Marketing-Consent Gated The pixel script mounts only after marketing consent is granted — identical handling to Meta Pixel (X Ads is a marketing cookie). When consent is missing the pixel is not loaded and conversion calls are silent no-ops.
Automatic Page View The base twq('config', ID) call auto-tracks page views — no manual PageView event is fired (avoids double-counting).
Auto-Fired: Purchase Fires on trackConversion() via xEvents.purchase({ value, currency, transactionId }) — uses NEXT_PUBLIC_X_PIXEL_EVENT_PURCHASE. Same call also fires Google Ads + GTM + Meta Pixel purchase events.
Auto-Fired: Signup Fires on trackSignUp() via xEvents.signUp() — uses NEXT_PUBLIC_X_PIXEL_EVENT_SIGNUP. Triggered on onboarding completion.
Pre-built Events xEvents.purchase(), .signUp(), .lead() (reuses signup ID), .custom(eventId, params) for additional conversion actions. Each no-ops cleanly when its env var is unset, so calling unconditionally is safe.
Security (Env Var Validation) Pixel ID is validated against /^[A-Za-z0-9]{3,12}$/ and event IDs against /^tw-[A-Za-z0-9]+-[A-Za-z0-9]+$/ before injection into the inline script — prevents XSS via malformed env values. Invalid IDs are silently dropped (component renders null).
CSP-Compliant Script receives the per-request nonce via the nonce prop. static.ads-twitter.com is in SCRIPT_CDN_ALLOWLIST and analytics.twitter.com / t.co are in CONNECT_CDN_ALLOWLIST in lib/security/csp.ts.

Crisp Chat

Live chat widget for customer support. Configure with NEXT_PUBLIC_CRISP_WEBSITE_ID.

Feature Description
User Identification Automatically identifies logged-in users with email, name, avatar
Company Data Associates users with their workspace/company
Custom Data Sends subscription plan, credits balance, account type
Locale Support Chat interface matches user's locale
Programmatic Control Open, close, hide, show, and send messages via API