feat: add GA4 custom event tracking for configurator and voice agent
All checks were successful
Build & Push / build-and-push (push) Successful in 1m23s
All checks were successful
Build & Push / build-and-push (push) Successful in 1m23s
Events tracked: - configurator_step_completed (with step number) - configurator_brief_generated (with services and AI flag) - voice_agent_started - voice_agent_brief_generated Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
import { useState } from 'react';
|
||||
import { useLocale, useTranslations } from 'next-intl';
|
||||
import { AnimatePresence, motion } from 'framer-motion';
|
||||
import { trackEvent } from '@/lib/analytics';
|
||||
import StepServices from './StepServices';
|
||||
import StepDetails from './StepDetails';
|
||||
import StepContact from './StepContact';
|
||||
@@ -90,7 +91,11 @@ export default function WizardContainer() {
|
||||
|
||||
const goNext = () => {
|
||||
setDirection(1);
|
||||
setCurrentStep((prev) => Math.min(prev + 1, 4) as 1 | 2 | 3 | 4);
|
||||
setCurrentStep((prev) => {
|
||||
const next = Math.min(prev + 1, 4) as 1 | 2 | 3 | 4;
|
||||
trackEvent('configurator_step_completed', { step: prev });
|
||||
return next;
|
||||
});
|
||||
};
|
||||
|
||||
const goBack = () => {
|
||||
@@ -131,6 +136,10 @@ export default function WizardContainer() {
|
||||
setDirection(1);
|
||||
setIsGenerating(false);
|
||||
setCurrentStep(4);
|
||||
trackEvent('configurator_brief_generated', {
|
||||
services: formData.services.join(','),
|
||||
ai_enabled: formData.aiEnabled,
|
||||
});
|
||||
} catch {
|
||||
setSubmitError(t('errors.network'));
|
||||
setIsGenerating(false);
|
||||
|
||||
@@ -5,6 +5,7 @@ import { useLocale, useTranslations } from 'next-intl';
|
||||
import { motion, AnimatePresence } from 'framer-motion';
|
||||
import { MessageCircle } from 'lucide-react';
|
||||
import { revealVariants, staggerContainer, viewportOnce } from '@/lib/animations';
|
||||
import { trackEvent } from '@/lib/analytics';
|
||||
import VoiceAgentProvider from '@/components/configurator/VoiceAgentProvider';
|
||||
import VoiceAgent from '@/components/configurator/VoiceAgent';
|
||||
import StepComplete from '@/components/configurator/StepComplete';
|
||||
@@ -36,6 +37,7 @@ export default function Discovery() {
|
||||
|
||||
const handleOpen = () => {
|
||||
setIsOpen(true);
|
||||
trackEvent('voice_agent_started');
|
||||
// Scroll to panel after it renders
|
||||
requestAnimationFrame(() => {
|
||||
panelRef.current?.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
||||
@@ -44,6 +46,7 @@ export default function Discovery() {
|
||||
|
||||
const handleComplete = (brief: string, formData: WizardFormData) => {
|
||||
setCompleted({ brief, formData });
|
||||
trackEvent('voice_agent_brief_generated');
|
||||
};
|
||||
|
||||
const handleReset = () => {
|
||||
|
||||
12
src/lib/analytics.ts
Normal file
12
src/lib/analytics.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* Send a custom event to Google Analytics 4.
|
||||
* Safe to call anywhere — silently no-ops if gtag isn't loaded.
|
||||
*/
|
||||
export function trackEvent(
|
||||
eventName: string,
|
||||
params?: Record<string, string | number | boolean>,
|
||||
) {
|
||||
if (typeof window !== 'undefined' && typeof window.gtag === 'function') {
|
||||
window.gtag('event', eventName, params)
|
||||
}
|
||||
}
|
||||
3
src/types/global.d.ts
vendored
Normal file
3
src/types/global.d.ts
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
interface Window {
|
||||
gtag?: (...args: unknown[]) => void
|
||||
}
|
||||
Reference in New Issue
Block a user