From 5e845ad42c82d97de36c329bae5f6158c250a2d6 Mon Sep 17 00:00:00 2001 From: myelinated-wackerow <263208946+myelinated-wackerow@users.noreply.github.com> Date: Mon, 27 Apr 2026 09:44:25 -0700 Subject: [PATCH] fix(tracking): passive section view [Fixes #18047] Six TrackedSection wrappers on the new homepage auto-fired section_view events via IntersectionObserver with no user input. Matomo counts events as actions, so the homepage's bounce rate became incomparable with other pages and pre-launch baselines (apparent 56% -> 33% post-launch was largely an instrumentation artifact). Removes the wrappers from app/[locale]/page.tsx, deletes the unused component, and adds a comment on trackCustomEvent flagging it as user-initiated only to prevent recurrence. Co-Authored-By: Claude Opus 4.7 Co-Authored-By: wackerow <54227730+wackerow@users.noreply.github.com> --- app/[locale]/page.tsx | 106 +++++++++++++----------------- src/components/TrackedSection.tsx | 54 --------------- src/lib/utils/matomo.ts | 3 + 3 files changed, 48 insertions(+), 115 deletions(-) delete mode 100644 src/components/TrackedSection.tsx diff --git a/app/[locale]/page.tsx b/app/[locale]/page.tsx index 9f3267d1020..3209c27a2d8 100644 --- a/app/[locale]/page.tsx +++ b/app/[locale]/page.tsx @@ -15,7 +15,6 @@ import GetStartedGrid from "@/components/Homepage/GetStartedGrid" import TrustLogos from "@/components/Homepage/TrustLogos" import I18nProvider from "@/components/I18nProvider" import MainArticle from "@/components/MainArticle" -import { TrackedSection } from "@/components/TrackedSection" import { BaseLink } from "@/components/ui/Link" import { SectionHeader, SectionTag } from "@/components/ui/section" @@ -84,66 +83,51 @@ const Page = async (props: { params: Promise }) => {
- - - - - - - - - - - - - - - - {t("page-index-simulator-tag")} - - - {t("page-index-simulator-title")} - -

- {t("page-index-simulator-subtitle")} -

-
- } - footer={ - - {t("page-index-simulator-cta")} - - - } - /> - - - - - - - - - + + + + + + + + + {t("page-index-simulator-tag")} + + + {t("page-index-simulator-title")} + +

+ {t("page-index-simulator-subtitle")} +

+ + } + footer={ + + {t("page-index-simulator-cta")} + + + } + /> + + + + diff --git a/src/components/TrackedSection.tsx b/src/components/TrackedSection.tsx deleted file mode 100644 index b021ab180e1..00000000000 --- a/src/components/TrackedSection.tsx +++ /dev/null @@ -1,54 +0,0 @@ -"use client" - -import { useEffect, useRef } from "react" -import { useIntersectionObserver } from "usehooks-ts" -import { Slot } from "@radix-ui/react-slot" - -import { trackCustomEvent } from "@/lib/utils/matomo" - -type TrackedSectionProps = { - id: string - eventCategory: string - children: React.ReactNode - asChild?: boolean -} - -export function TrackedSection({ - id, - eventCategory, - children, - asChild = false, -}: TrackedSectionProps) { - const { ref, isIntersecting } = useIntersectionObserver({ threshold: 0.3 }) - const hasTrackedView = useRef(false) - const timerRef = useRef(null) - - // Track section_view after 1 second of visibility - useEffect(() => { - if (isIntersecting && !hasTrackedView.current) { - timerRef.current = setTimeout(() => { - trackCustomEvent({ - eventCategory, - eventAction: "section_view", - eventName: id, - }) - hasTrackedView.current = true - }, 1000) - } else if (!isIntersecting && timerRef.current) { - clearTimeout(timerRef.current) - timerRef.current = null - } - - return () => { - if (timerRef.current) clearTimeout(timerRef.current) - } - }, [isIntersecting, eventCategory, id]) - - const Comp = asChild ? Slot : "div" - - return ( - - {children} - - ) -} diff --git a/src/lib/utils/matomo.ts b/src/lib/utils/matomo.ts index c04ca7d1f9f..61322e59bf5 100644 --- a/src/lib/utils/matomo.ts +++ b/src/lib/utils/matomo.ts @@ -28,6 +28,9 @@ const scheduleIdleCallback = ? requestIdleCallback : (cb: () => void) => setTimeout(cb, 0) +// Use only for user-initiated actions (clicks, submits, swipes). Passive +// visibility/scroll tracking inflates `nb_actions` and breaks bounce-rate +// comparability with pages that don't auto-fire events. export const trackCustomEvent = ({ eventCategory, eventAction,