diff --git a/.docs/reference/tracking.md b/.docs/reference/tracking.md index 2bd2de5..4e64c4e 100644 --- a/.docs/reference/tracking.md +++ b/.docs/reference/tracking.md @@ -21,14 +21,14 @@ Le site attire du trafic via le blog (79 articles) et les pages service. Sans tr | Event | Composant | Fichier | Parametres | |-------|-----------|---------|------------| -| `form_submit` | ContactForm | `src/components/sections/ContactForm.tsx` | `form_type: "contact"`, `subject` | -| `form_submit` | AuditForm | `src/components/sections/AuditForm.tsx` | `form_type: "audit"`, `symfony_version`, `team_size`, `problem` | +| `form_submit` | ContactForm | `src/components/sections/ContactForm.tsx` | `form_name: "contact"`, `source_page`, `subject` | +| `audit_requested` | AuditForm | `src/components/sections/AuditForm.tsx` | `form_name: "audit"`, `source_page`, `symfony_version`, `team_size`, `problem` | +| `email_clicked` | TrackedEmailLink | `src/components/ui/TrackedEmailLink.tsx` | `source_location: "footer"` (par defaut) | | `cta_click` | CallToAction | `src/components/sections/CallToAction.tsx` | `cta_location: "footer_cta"`, `cta_text` | | `cta_click` | StickyMobileCta | `src/components/sections/StickyMobileCta.tsx` | `cta_location: "sticky_mobile"`, `cta_text` | | `cta_click` | MobileMenu | `src/components/layout/MobileMenu.tsx` | `cta_location: "header_mobile"`, `cta_text` | | `cta_click` | HeaderCtas | `src/components/layout/HeaderCtas.tsx` | `cta_location: "header_desktop"`, `cta_text` | | `cta_click` | TrackedArticleButton | `src/components/sections/TrackedArticleButton.tsx` | `cta_location: "article_body"`, `cta_text`, `article_slug` | -| `cta_click` | Footer email | `src/components/layout/Footer.tsx` | `cta_location: "footer"`, `cta_text: "email_contact"` | | `scroll_depth` | ScrollDepthTracker | `src/components/ui/ScrollDepthTracker.tsx` | `event_label: slug`, `scroll_percent: "25%/50%/75%/100%"` | | `share` | ArticleShareButtons | `src/components/ui/ArticleShareButtons.tsx` | `method: "linkedin" / "twitter" / "copy_link"`, `article_slug` | @@ -60,11 +60,12 @@ Le site attire du trafic via le blog (79 articles) et les pages service. Sans tr ### Conventions de nommage - Noms d'events en `snake_case` -- `form_submit` pour les soumissions de formulaire -- `cta_click` pour les clics sur les boutons d'action -- `scroll_depth` pour le suivi de lecture -- `cta_location` identifie ou se trouve le CTA (header, footer, sticky, etc.) -- `cta_text` reprend le texte visible du bouton +- Conversion grade : `form_submit`, `audit_requested`, `email_clicked` (a marquer comme "conversions cles" dans GA4 admin) +- Engagement : `cta_click`, `scroll_depth`, `share` +- `form_name` identifie le formulaire concerne (`contact`, `audit`) +- `source_page` capture `window.location.pathname` au moment de la soumission +- `source_location` identifie ou se trouve l'element (footer, header, etc.) +- `cta_location` / `cta_text` pour les clics CTA ## Explication @@ -78,7 +79,7 @@ ArticleCta reste un server component. Seul le bouton est un client component (`T ### Limites actuelles -- Les formulaires utilisent `mailto:` : le tracking fire avant l'ouverture du client mail, mais ne garantit pas que l'email est effectivement envoye. +- Les formulaires utilisent `mailto:` : le tracking fire avant l'ouverture du client mail, mais ne garantit pas que l'email est effectivement envoye. `form_submit` et `audit_requested` mesurent donc une intention de soumission, pas un succes d'envoi confirme. A migrer vers du tracking backend-confirmed quand le backend des formulaires sera en place. ### Evolutions possibles diff --git a/src/__tests__/components/ui/TrackedEmailLink.test.tsx b/src/__tests__/components/ui/TrackedEmailLink.test.tsx index 962ad91..865d862 100644 --- a/src/__tests__/components/ui/TrackedEmailLink.test.tsx +++ b/src/__tests__/components/ui/TrackedEmailLink.test.tsx @@ -37,9 +37,20 @@ describe("TrackedEmailLink", () => { render(); fireEvent.click(screen.getByText("test@example.com")); - expect(gtagSpy).toHaveBeenCalledWith("event", "cta_click", { - cta_location: "footer", - cta_text: "email_contact", + expect(gtagSpy).toHaveBeenCalledWith("event", "email_clicked", { + source_location: "footer", + }); + }); + + it("uses the provided sourceLocation prop", () => { + const gtagSpy = jest.fn(); + window.gtag = gtagSpy; + + render(); + fireEvent.click(screen.getByText("test@example.com")); + + expect(gtagSpy).toHaveBeenCalledWith("event", "email_clicked", { + source_location: "header", }); }); }); diff --git a/src/__tests__/lib/tracking.test.ts b/src/__tests__/lib/tracking.test.ts index 0e196a3..e7f8705 100644 --- a/src/__tests__/lib/tracking.test.ts +++ b/src/__tests__/lib/tracking.test.ts @@ -15,10 +15,10 @@ describe("trackEvent", () => { const gtagSpy = jest.fn(); window.gtag = gtagSpy; - trackEvent("form_submit", { form_type: "contact" }); + trackEvent("form_submit", { form_name: "contact" }); expect(gtagSpy).toHaveBeenCalledWith("event", "form_submit", { - form_type: "contact", + form_name: "contact", }); }); @@ -31,15 +31,15 @@ describe("trackEvent", () => { const gtagSpy = jest.fn(); window.gtag = gtagSpy; - trackEvent("form_submit", { - form_type: "audit", + trackEvent("audit_requested", { + form_name: "audit", symfony_version: "7.x", team_size: "3-5", problem: "Performance", }); - expect(gtagSpy).toHaveBeenCalledWith("event", "form_submit", { - form_type: "audit", + expect(gtagSpy).toHaveBeenCalledWith("event", "audit_requested", { + form_name: "audit", symfony_version: "7.x", team_size: "3-5", problem: "Performance", diff --git a/src/components/sections/AuditForm.tsx b/src/components/sections/AuditForm.tsx index 90c7c99..4944218 100644 --- a/src/components/sections/AuditForm.tsx +++ b/src/components/sections/AuditForm.tsx @@ -48,8 +48,9 @@ export default function AuditForm() { `${data.get("message") || ""}`, ].join("\n"); - trackEvent("form_submit", { - form_type: "audit", + trackEvent("audit_requested", { + form_name: "audit", + source_page: window.location.pathname, symfony_version: data.get("symfonyVersion") as string, team_size: data.get("teamSize") as string, problem: data.get("problem") as string, diff --git a/src/components/sections/ContactForm.tsx b/src/components/sections/ContactForm.tsx index 5bb7779..ffa83b3 100644 --- a/src/components/sections/ContactForm.tsx +++ b/src/components/sections/ContactForm.tsx @@ -25,7 +25,8 @@ export default function ContactForm() { const body = `Nom: ${data.get("name")}\nEntreprise: ${data.get("company")}\nTéléphone: ${data.get("phone")}\nEmail: ${data.get("email")}\n\n${data.get("message")}`; trackEvent("form_submit", { - form_type: "contact", + form_name: "contact", + source_page: window.location.pathname, subject, }); diff --git a/src/components/ui/TrackedEmailLink.tsx b/src/components/ui/TrackedEmailLink.tsx index 06c91ab..f1fb591 100644 --- a/src/components/ui/TrackedEmailLink.tsx +++ b/src/components/ui/TrackedEmailLink.tsx @@ -4,15 +4,20 @@ import { trackEvent } from "@/lib/tracking"; interface TrackedEmailLinkProps { email: string; + sourceLocation?: string; className?: string; } -export default function TrackedEmailLink({ email, className }: TrackedEmailLinkProps) { +export default function TrackedEmailLink({ + email, + sourceLocation = "footer", + className, +}: TrackedEmailLinkProps) { return ( trackEvent("cta_click", { cta_location: "footer", cta_text: "email_contact" })} + onClick={() => trackEvent("email_clicked", { source_location: sourceLocation })} > {email} diff --git a/src/lib/tracking.ts b/src/lib/tracking.ts index 367492b..d552ee8 100644 --- a/src/lib/tracking.ts +++ b/src/lib/tracking.ts @@ -1,7 +1,9 @@ type GtagEvent = { event_category?: string; event_label?: string; - form_type?: string; + form_name?: string; + source_page?: string; + source_location?: string; cta_location?: string; cta_text?: string; subject?: string;