Skip to content

Commit b9a51ca

Browse files
committed
Add analytics tracking to homepage sections and CTAs
Introduced analytics tracking for section views and CTA clicks across the homepage. GallerySection now tracks when it enters the viewport, HeroSection and ServicesSection track CTA button clicks, and Home.tsx tracks when each main section becomes visible. This enables better insight into user engagement.
1 parent 050b8ed commit b9a51ca

4 files changed

Lines changed: 56 additions & 0 deletions

File tree

client/src/components/GallerySection.tsx

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { useEffect, useMemo, useRef, useState } from "react";
22
import AnimatedElement from "@/lib/AnimatedElement";
33
import ImageWithFallback from "@/lib/ImageWithFallback";
4+
import { trackGalleryView } from "@/lib/analytics";
45

56
interface GalleryImage { src: string; alt: string }
67

@@ -33,6 +34,26 @@ export default function GallerySection() {
3334
// Measure the exact pixel distance for half track and compute duration = distance / speed
3435
const trackRef = useRef<HTMLDivElement>(null);
3536
const [styleVars, setStyleVars] = useState<React.CSSProperties>({});
37+
const hasTrackedView = useRef(false);
38+
39+
useEffect(() => {
40+
// Analytics tracking when gallery comes into view
41+
const observer = new IntersectionObserver(
42+
(entries) => {
43+
if (entries[0].isIntersecting && !hasTrackedView.current) {
44+
trackGalleryView();
45+
hasTrackedView.current = true;
46+
}
47+
},
48+
{ threshold: 0.2 }
49+
);
50+
51+
if (trackRef.current) {
52+
observer.observe(trackRef.current);
53+
}
54+
55+
return () => observer.disconnect();
56+
}, []);
3657

3758
useEffect(() => {
3859
const measure = () => {

client/src/components/HeroSection.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { motion } from "framer-motion";
22
import ParticleCanvas from "./ParticleCanvas";
33
import { FaChevronDown } from "react-icons/fa";
4+
import { trackCTAClick } from "@/lib/analytics";
45

56
const HeroSection = () => {
67
return (
@@ -53,12 +54,14 @@ const HeroSection = () => {
5354
>
5455
<a
5556
href="#builds"
57+
onClick={() => trackCTAClick('Scopri le Build', 'hero')}
5658
className="bg-[#ff7514] hover:bg-[#e06500] text-black font-semibold py-3 px-8 rounded-md transition-all transform hover:scale-105"
5759
>
5860
Scopri le Build
5961
</a>
6062
<a
6163
href="#contact"
64+
onClick={() => trackCTAClick('Contattaci', 'hero')}
6265
className="bg-transparent border-2 border-white hover:border-[#ff7514] hover:text-[#ff7514] text-white font-medium py-3 px-8 rounded-md transition-all transform hover:scale-105"
6366
>
6467
Contattaci

client/src/components/ServicesSection.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { FaDesktop, FaTools, FaTachometerAlt, FaCheck, FaArrowRight } from "react-icons/fa";
22
import AnimatedElement from "@/lib/AnimatedElement";
3+
import { trackCTAClick } from "@/lib/analytics";
34

45
const ServiceCard = ({
56
icon,
@@ -34,6 +35,7 @@ const ServiceCard = ({
3435
</ul>
3536
<a
3637
href="#contact"
38+
onClick={() => trackCTAClick(cta, 'services')}
3739
className="inline-block text-[#ff7514] hover:underline font-medium group"
3840
>
3941
{cta} <FaArrowRight className="inline ml-1 transform group-hover:translate-x-1 transition-transform" />

client/src/pages/Home.tsx

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,42 @@
1+
import { useEffect, useRef } from "react";
12
import HeroSection from "@/components/HeroSection";
23
import ServicesSection from "@/components/ServicesSection";
34
import GallerySection from "@/components/GallerySection";
45
import BuildsSection from "@/components/BuildsSection";
56
import ComponentsSection from "@/components/ComponentsSection";
67
import AppsSection from "@/components/AppsSection";
78
import ContactSection from "@/components/ContactSection";
9+
import { trackSectionView } from "@/lib/analytics";
810

911
const Home = () => {
12+
const sectionsRef = useRef<Map<string, boolean>>(new Map());
13+
14+
useEffect(() => {
15+
const observer = new IntersectionObserver(
16+
(entries) => {
17+
entries.forEach((entry) => {
18+
if (entry.isIntersecting) {
19+
const sectionId = entry.target.id;
20+
// Only track each section once per session
21+
if (sectionId && !sectionsRef.current.get(sectionId)) {
22+
trackSectionView(sectionId);
23+
sectionsRef.current.set(sectionId, true);
24+
}
25+
}
26+
});
27+
},
28+
{ threshold: 0.3 } // Trigger when 30% of section is visible
29+
);
30+
31+
// Observe all sections
32+
const sections = document.querySelectorAll('section[id]');
33+
sections.forEach((section) => observer.observe(section));
34+
35+
return () => {
36+
sections.forEach((section) => observer.unobserve(section));
37+
};
38+
}, []);
39+
1040
return (
1141
<div className="overflow-hidden">
1242
<HeroSection />

0 commit comments

Comments
 (0)