Skip to content

Commit

Permalink
Add search tracking in Matomo
Browse files Browse the repository at this point in the history
  • Loading branch information
eletallbetagouv committed Sep 19, 2024
1 parent 3406442 commit 3655c27
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 20 deletions.
8 changes: 4 additions & 4 deletions website/src/analytic/AnalyticContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {Analytic} from './analytic'

export interface AnalyticContextProps {
trackEvent: Analytic['trackEvent']
trackSearch: Analytic['trackSearch']
}

interface Props {
Expand All @@ -19,10 +20,9 @@ export const AnalyticProvider = ({analytic, children}: Props) => {
return (
<AnalyticContext.Provider
value={{
trackEvent:
analytic?.trackEvent ??
// analytics are not available server-side
((...args: any[]) => {}),
// analytics are not available server-side
trackEvent: analytic?.trackEvent ?? (() => {}),
trackSearch: analytic?.trackSearch ?? (() => {}),
}}
>
{children}
Expand Down
22 changes: 21 additions & 1 deletion website/src/analytic/analytic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export class Analytic {
return new Analytic(matomo, eularian)
}

private log = (...args: (string | undefined)[]) => {
private log = (...args: unknown[]) => {
console.debug('[Analytic]', ...args)
}

Expand All @@ -37,6 +37,26 @@ export class Analytic {
}
}
}

readonly trackSearch = (
inputs: {q: string; postalCode?: string; departmentCode?: string},
searchCategory: 'companysearch_smart' | 'companysearch_nameandpostalcode' | 'companysearch_name' | 'companysearch_siret',
nbResults: number,
) => {
const {q, postalCode, departmentCode} = inputs
const trackedSearch = `${postalCode ? `[${postalCode}] ` : ''}${departmentCode ? `[${departmentCode}] ` : ''}${q}`
const args = ['[trackSiteSearch]', trackedSearch, searchCategory, nbResults]
this.log(...args)
try {
// https://developer.matomo.org/guides/tracking-javascript-guide#internal-search-tracking
this.matomo?.push(args)
} catch (e: any) {
console.error('[Analytic]', e)
if (!(e instanceof ReferenceError)) {
throw e
}
}
}
}

export function PageChangesListener({analytic}: {analytic: Analytic}) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,11 @@ export const CompanySearchByIdentifier = ({children}: Props) => {
const [submittedIdentity, setSubmittedIdentity] = useState<string | undefined>(undefined)
const _searchByIdentity = useQuery({
queryKey: ['searchCompaniesByIdentity', submittedIdentity],
queryFn: () => {
queryFn: async () => {
if (submittedIdentity) {
return companyApiClient.searchCompaniesByIdentity(submittedIdentity, false, currentLang)
const res = await companyApiClient.searchCompaniesByIdentity(submittedIdentity, false, currentLang)
_analytic.trackSearch({q: submittedIdentity}, 'companysearch_siret', res.length)
return res
}
return null
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import {CompanySearchResult} from '@/model/Company'
import {ReactNode, useState} from 'react'
import {useI18n} from '@/i18n/I18n'
import {useApiClients} from '@/context/ApiClientsContext'
import {useQuery} from '@tanstack/react-query'
import {useToastOnQueryError} from '@/clients/apiHooks'
import {useAnalyticContext} from '@/analytic/AnalyticContext'
import {useForm} from 'react-hook-form'
import {CompanySearchEventActions, EventCategories} from '@/analytic/analytic'
import {useToastOnQueryError} from '@/clients/apiHooks'
import {Animate} from '@/components_simple/Animate'
import {RequiredFieldsLegend} from '@/components_simple/RequiredFieldsLegend'
import {ScTextInput} from '@/components_simple/formInputs/ScTextInput'
import {ButtonWithLoader} from '@/components_simple/buttons/Buttons'
import {ScTextInput} from '@/components_simple/formInputs/ScTextInput'
import {useApiClients} from '@/context/ApiClientsContext'
import {useI18n} from '@/i18n/I18n'
import {CompanySearchResult} from '@/model/Company'
import {ifDefined} from '@/utils/utils'
import {useQuery} from '@tanstack/react-query'
import {ReactNode, useState} from 'react'
import {useForm} from 'react-hook-form'

interface Form {
name: string
Expand All @@ -27,9 +27,12 @@ export const CompanySearchByName = ({children}: Props) => {
const [submittedForm, setSubmittedForm] = useState<Form | undefined>()
const _search = useQuery({
queryKey: ['searchHeadOfficesByName', submittedForm?.name],
queryFn: () => {
queryFn: async () => {
if (submittedForm) {
return companyApiClient.searchHeadOfficesByName(submittedForm.name, currentLang)
const {name} = submittedForm
const res = await companyApiClient.searchHeadOfficesByName(name, currentLang)
_analytic.trackSearch({q: name}, 'companysearch_name', res.length)
return res
}
return null
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,12 @@ export const CompanySearchByNameAndPostalCode = ({children}: Props) => {
const [submittedForm, setSubmittedForm] = useState<Form | undefined>()
const _search = useQuery({
queryKey: ['searchCompaniesByNameAndPostalCode', submittedForm?.name, submittedForm?.postalCode],
queryFn: () => {
queryFn: async () => {
if (submittedForm) {
return companyApiClient.searchCompaniesByNameAndPostalCode(submittedForm.name, submittedForm.postalCode, currentLang)
const {name, postalCode} = submittedForm
const res = await companyApiClient.searchCompaniesByNameAndPostalCode(name, postalCode, currentLang)
_analytic.trackSearch({q: name, postalCode}, 'companysearch_nameandpostalcode', res.length)
return res
}
return null
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import {useAnalyticContext} from '@/analytic/AnalyticContext'
import {useToastOnQueryError} from '@/clients/apiHooks'
import {Animate} from '@/components_simple/Animate'
import {useApiClients} from '@/context/ApiClientsContext'
Expand Down Expand Up @@ -139,14 +140,17 @@ export function CompanySmartIdentification({
function useCompanySearchSmartQuery(searchInputs: CompanySearchInputs | undefined) {
const {companyApiClient} = useApiClients()
const {currentLang} = useI18n()
const _analytic = useAnalyticContext()
const _search = useQuery({
queryKey: ['searchCompany', searchInputs],
queryFn: async () => {
if (searchInputs) {
const {input, geoArea} = searchInputs
const postalCode = geoArea && geoArea.kind === 'postcode' ? geoArea.postalCode : undefined
const departmentCode = geoArea && geoArea.kind === 'department' ? geoArea.dpt.code : undefined
return companyApiClient.searchSmart(input, postalCode, departmentCode, currentLang)
const res = await companyApiClient.searchSmart(input, postalCode, departmentCode, currentLang)
_analytic.trackSearch({q: input, postalCode, departmentCode}, 'companysearch_smart', res.length)
return res
}
return null
},
Expand Down

0 comments on commit 3655c27

Please sign in to comment.