diff --git a/infra/roles/camino/templates/env b/infra/roles/camino/templates/env
index 947d7ce27c9be8cb1548a7478c44d6e4bf5fa329..7d428bb0fd87960e6b1c99ca41b828978cf8c50b 100644
--- a/infra/roles/camino/templates/env
+++ b/infra/roles/camino/templates/env
@@ -74,9 +74,7 @@ API_INSEE_SECRET={{ api_insee_secret }}
 API_INSEE_URL="https://api.insee.fr"
 
 # API Matomo
-API_MATOMO_URL=https://stats.data.gouv.fr
-API_MATOMO_ID=70
-API_MATOMO_TOKEN={{ matomo_token }}
-API_MATOMO_MONTHS=24
+API_MATOMO_URL="http://audience-sites.din.developpement-durable.gouv.fr"
+API_MATOMO_ID=1667
 
 API_SENTRY_URL={{ api_sentry_url }}
\ No newline at end of file
diff --git a/knip.ts b/knip.ts
index bf216f5b599ed1424a5f1a8a6350f176f821ef05..f0ee1c35149a0b5b6a14e2716f364c4f36889a36 100644
--- a/knip.ts
+++ b/knip.ts
@@ -31,7 +31,7 @@ const config = {
       "project": "**/*.ts",
       ignoreDependencies: [
         // TODO 2023-12-28 ces dépendances semblent être "shadow" par les définitions bourrines .d.ts qu'on a mise
-        "graphql-fields", "graphql-scalars", "html-to-text", "matomo-tracker",
+        "graphql-fields", "graphql-scalars", "html-to-text", 
         "@vitest/coverage-v8", "@pgtyped/cli"
       ]
     },
diff --git a/package-lock.json b/package-lock.json
index f47dfcedf05050f9833449fdefa598dd7572ad73..0fdb362172cba2a88caa0b8d793f867a7972235f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -19447,14 +19447,6 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/matomo-tracker": {
-      "version": "2.2.4",
-      "resolved": "https://registry.npmjs.org/matomo-tracker/-/matomo-tracker-2.2.4.tgz",
-      "integrity": "sha512-7fDy4wRhDQ1dnSxVqmnVqmmos9ACKag0fCBtBD3/Qeoqks7MFqXcO35nfS6S8xU/IXNf7534q/4Gx8fuWKYW6A==",
-      "engines": {
-        "node": ">=4.2.0"
-      }
-    },
     "node_modules/md5-hex": {
       "version": "3.0.1",
       "resolved": "https://registry.npmjs.org/md5-hex/-/md5-hex-3.0.1.tgz",
@@ -29916,7 +29908,6 @@
         "jsonwebtoken": "^9.0.0",
         "jszip": "^3.10.1",
         "knex": "^2.4.2",
-        "matomo-tracker": "^2.2.4",
         "node-mailjet": "^6.0.2",
         "objection": "github:Vincit/objection.js#dbb20aebaac2059149ec18386283b3cce4a3d7f0",
         "pg": "^8.11.0",
@@ -42622,7 +42613,6 @@
         "jsonwebtoken": "^9.0.0",
         "jszip": "^3.10.1",
         "knex": "^2.4.2",
-        "matomo-tracker": "^2.2.4",
         "node-mailjet": "^6.0.2",
         "objection": "github:Vincit/objection.js#dbb20aebaac2059149ec18386283b3cce4a3d7f0",
         "pg": "^8.11.0",
@@ -50193,11 +50183,6 @@
         }
       }
     },
-    "matomo-tracker": {
-      "version": "2.2.4",
-      "resolved": "https://registry.npmjs.org/matomo-tracker/-/matomo-tracker-2.2.4.tgz",
-      "integrity": "sha512-7fDy4wRhDQ1dnSxVqmnVqmmos9ACKag0fCBtBD3/Qeoqks7MFqXcO35nfS6S8xU/IXNf7534q/4Gx8fuWKYW6A=="
-    },
     "md5-hex": {
       "version": "3.0.1",
       "resolved": "https://registry.npmjs.org/md5-hex/-/md5-hex-3.0.1.tgz",
diff --git a/packages/api/package.json b/packages/api/package.json
index 29c994d97098ab8548c380e20f7676aa3b919a93..4e9ecfee54e8774c52073f21cdacea183f341df8 100644
--- a/packages/api/package.json
+++ b/packages/api/package.json
@@ -79,7 +79,6 @@
     "jsonwebtoken": "^9.0.0",
     "jszip": "^3.10.1",
     "knex": "^2.4.2",
-    "matomo-tracker": "^2.2.4",
     "node-mailjet": "^6.0.2",
     "objection": "github:Vincit/objection.js#dbb20aebaac2059149ec18386283b3cce4a3d7f0",
     "pg": "^8.11.0",
diff --git a/packages/api/src/@types/matomo-tracker.d.ts b/packages/api/src/@types/matomo-tracker.d.ts
deleted file mode 100644
index 67cd699d5419c096a8956bb5411af5ad0e28b29f..0000000000000000000000000000000000000000
--- a/packages/api/src/@types/matomo-tracker.d.ts
+++ /dev/null
@@ -1 +0,0 @@
-declare module 'matomo-tracker'
diff --git a/packages/api/src/api/graphql/resolvers/statistiques.ts b/packages/api/src/api/graphql/resolvers/statistiques.ts
index fd9720deeab72b7e71a888918541c1c3e8c8c1d3..30f23576f44cf9fcbb78fb85690d3af4caef1b1a 100644
--- a/packages/api/src/api/graphql/resolvers/statistiques.ts
+++ b/packages/api/src/api/graphql/resolvers/statistiques.ts
@@ -1,31 +1,26 @@
-import { ITitre } from '../../../types.js'
+import { Context, ITitre } from '../../../types.js'
 
 import { titreEtapePropFind } from '../../../business/rules/titre-etape-prop-find.js'
 import { titreValideCheck } from '../../../business/utils/titre-valide-check.js'
 import { titresActivitesGet } from '../../../database/queries/titres-activites.js'
 import { userSuper } from '../../../database/user-super.js'
-import { matomoData } from '../../../tools/api-matomo/index.js'
 import { Statistiques } from 'camino-common/src/statistiques.js'
 import { TitreTypeId } from 'camino-common/src/static/titresTypes.js'
 import { DEMARCHES_TYPES_IDS } from 'camino-common/src/static/demarchesTypes.js'
 import { ACTIVITES_STATUTS_IDS } from 'camino-common/src/static/activitesStatuts.js'
 import { getAnnee, toCaminoDate } from 'camino-common/src/date.js'
 import { isNotNullNorUndefined } from 'camino-common/src/typescript-tools.js'
+import { getTitresModifiesByMonth } from '../../rest/journal.queries.js'
 
 const ACTIVITE_ANNEE_DEBUT = 2018
 
-export const statistiquesGlobales = async (): Promise<Statistiques> => {
+export const statistiquesGlobales = async (_: unknown, { pool }: Context): Promise<Statistiques> => {
   try {
     const titresActivites = await titresActivitesGet({}, {}, userSuper)
-
     const titresActivitesDepose = titresActivites.filter(titreActivite => titreActivite.annee >= ACTIVITE_ANNEE_DEBUT && titreActivite.activiteStatutId === ACTIVITES_STATUTS_IDS.DEPOSE).length
-
     const titresActivitesBeneficesEntreprise = Math.round((titresActivitesDepose * 2) / 7)
-
     const titresActivitesBeneficesAdministration = Math.round((titresActivitesDepose * 1) / 7)
-
-    const { recherches, titresModifies, actions, sessionDuree, telechargements, signalements, reutilisations } = await matomoData()
-
+    const titresModifies = await getTitresModifiesByMonth(pool)
     const demarches = titresActivites.filter(titreActivite => {
       const dateSaisie = titreActivite.dateSaisie
 
@@ -35,14 +30,8 @@ export const statistiquesGlobales = async (): Promise<Statistiques> => {
     return {
       titresActivitesBeneficesEntreprise,
       titresActivitesBeneficesAdministration,
-      recherches,
       titresModifies,
-      actions,
-      sessionDuree,
-      telechargements,
       demarches,
-      signalements,
-      reutilisations,
     }
   } catch (e) {
     console.error(e)
diff --git a/packages/api/src/api/rest/index.ts b/packages/api/src/api/rest/index.ts
index 4694a2c3a522481dc10ae0f418b51055bc892580..a33e23169c7ee745b511121f7e80e6fa27960a55 100644
--- a/packages/api/src/api/rest/index.ts
+++ b/packages/api/src/api/rest/index.ts
@@ -16,7 +16,6 @@ import { titresDemarchesFormatTable } from './format/titres-demarches.js'
 import { titresActivitesFormatTable } from './format/titres-activites.js'
 import { entreprisesFormatTable } from './format/entreprises.js'
 
-import { matomo } from '../../tools/matomo.js'
 import { User } from 'camino-common/src/roles.js'
 import {
   CaminoFiltre,
@@ -201,30 +200,6 @@ export const titres =
         exhaustiveCheck(params.format)
     }
 
-    if (isNotNullNorUndefined(matomo)) {
-      const url = Object.entries({
-        format: params.format,
-        ordre: params.ordre,
-        colonne: params.colonne,
-        typesIds: params.typesIds,
-        domainesIds: params.domainesIds,
-        statutsIds: params.statutsIds,
-        substancesIds: params.substancesIds,
-        titresIds: params.titresIds,
-        entreprisesIds: params.entreprisesIds,
-        references: params.references,
-      })
-        .filter(param => param[1] !== undefined)
-        .map(param => param.join('='))
-        .join('&')
-
-      matomo.track({
-        url: `${process.env.API_MATOMO_URL}/matomo.php?${url}`,
-        e_c: 'camino-api',
-        e_a: `titres-flux-${params.format}`,
-      })
-    }
-
     return isNotNullNorUndefined(contenu)
       ? {
           nom: fileNameCreate(`titres-${titres.length}`, params.format),
diff --git a/packages/api/src/api/rest/journal.queries.ts b/packages/api/src/api/rest/journal.queries.ts
index fdba6a793a418d2cc8ea19e1a3c051353ee41559..e70e2539d59b58e307244efb65b25a438adb79fb 100644
--- a/packages/api/src/api/rest/journal.queries.ts
+++ b/packages/api/src/api/rest/journal.queries.ts
@@ -2,10 +2,11 @@
 import { sql } from '@pgtyped/runtime'
 import { TitreId } from 'camino-common/src/validators/titres.js'
 import { Redefine, dbQueryAndValidate } from '../../pg-database.js'
-import { IGetLastJournalInternalQuery } from './journal.queries.types.js'
+import { IGetLastJournalInternalQuery, IGetTitresModifiesByMonthDbQuery } from './journal.queries.types.js'
 import { CaminoDate, caminoDateValidator } from 'camino-common/src/date.js'
 import { z } from 'zod'
 import { Pool } from 'pg'
+import { QuantiteParMois, quantitesParMoisValidator } from 'camino-common/src/statistiques.js'
 
 const lastJournalGetValidator = z.object({ date: caminoDateValidator })
 type LastJournalGet = z.infer<typeof lastJournalGetValidator>
@@ -27,3 +28,21 @@ order by
     date desc
 LIMIT 1
 `
+
+export const getTitresModifiesByMonth = async (pool: Pool): Promise<QuantiteParMois[]> => {
+  return dbQueryAndValidate(getTitresModifiesByMonthDb, undefined, pool, quantitesParMoisValidator)
+}
+
+const getTitresModifiesByMonthDb = sql<Redefine<IGetTitresModifiesByMonthDbQuery, void, QuantiteParMois>>`
+select
+    concat(date_part('year', date), '-', to_char(date_part('month', date), 'fm00')) AS mois,
+    count(titre_id) as quantite
+from
+    journaux
+where
+    utilisateur_id != 'super'
+group by
+    mois
+order by
+    mois
+`
diff --git a/packages/api/src/api/rest/journal.queries.types.ts b/packages/api/src/api/rest/journal.queries.types.ts
index ae2af49a878b2a7ed30b7fee957d8d2c5e061d62..651d1cc76f018fd63aa333ae94c8cbd29d700491 100644
--- a/packages/api/src/api/rest/journal.queries.types.ts
+++ b/packages/api/src/api/rest/journal.queries.types.ts
@@ -16,3 +16,18 @@ export interface IGetLastJournalInternalQuery {
   result: IGetLastJournalInternalResult;
 }
 
+/** 'GetTitresModifiesByMonthDb' parameters type */
+export type IGetTitresModifiesByMonthDbParams = void;
+
+/** 'GetTitresModifiesByMonthDb' return type */
+export interface IGetTitresModifiesByMonthDbResult {
+  mois: string | null;
+  quantite: string | null;
+}
+
+/** 'GetTitresModifiesByMonthDb' query type */
+export interface IGetTitresModifiesByMonthDbQuery {
+  params: IGetTitresModifiesByMonthDbParams;
+  result: IGetTitresModifiesByMonthDbResult;
+}
+
diff --git a/packages/api/src/api/rest/journal.test.integration.ts b/packages/api/src/api/rest/journal.test.integration.ts
new file mode 100644
index 0000000000000000000000000000000000000000..0d762c071ee659b16cde662dc8884bfae16bccfe
--- /dev/null
+++ b/packages/api/src/api/rest/journal.test.integration.ts
@@ -0,0 +1,86 @@
+/* eslint-disable sql/no-unsafe-query */
+import { dbManager } from '../../../tests/db-manager.js'
+import { titreCreate } from '../../database/queries/titres.js'
+import { afterAll, beforeAll, test, expect, vi, describe } from 'vitest'
+import type { Pool } from 'pg'
+import { getTitresModifiesByMonth } from './journal.queries.js'
+import { Knex } from 'knex'
+import { idGenerate } from '../../database/models/_format/id-create.js'
+import { userGenerate } from '../../../tests/_utils/index.js'
+import { ITitre } from '../../types.js'
+
+console.info = vi.fn()
+console.error = vi.fn()
+
+let dbPool: Pool
+let knex: Knex
+
+let titre: ITitre
+beforeAll(async () => {
+  const { pool, knex: knexInstance } = await dbManager.populateDb()
+  dbPool = pool
+  knex = knexInstance
+
+  titre = await titreCreate(
+    {
+      nom: 'nomTitre',
+      typeId: 'arm',
+      titreStatutId: 'val',
+      propsTitreEtapesIds: {},
+    },
+    {}
+  )
+})
+
+afterAll(async () => {
+  await dbManager.closeKnex()
+})
+
+describe('getTitresModifiesByMonth', async () => {
+  test('ne prend pas en compte les modifications réalisées par l’utilisateur super', async () => {
+    let tested = await getTitresModifiesByMonth(dbPool)
+
+    await knex.raw(
+      `INSERT INTO public.journaux (id, utilisateur_id, date, element_id, operation, titre_id) VALUES ('${idGenerate()}', 'super', '2021-11-10 09:02:19.012000 +00:00', '${idGenerate()}', 'update', '${
+        titre.id
+      }')`
+    )
+    tested = await getTitresModifiesByMonth(dbPool)
+    expect(tested).toMatchInlineSnapshot('[]')
+  })
+
+  test('comptabilise chaque modifications sur chaque titres', async () => {
+    let tested = await getTitresModifiesByMonth(dbPool)
+
+    const user = await userGenerate({ role: 'defaut' })
+    await knex.raw(
+      `INSERT INTO public.journaux (id, utilisateur_id, date, element_id, operation, titre_id) VALUES ('${idGenerate()}', '${
+        user.id
+      }', '2021-11-10 09:02:19.012000 +00:00', '${idGenerate()}', 'update', '${titre.id}')`
+    )
+    tested = await getTitresModifiesByMonth(dbPool)
+    expect(tested).toMatchInlineSnapshot(`
+      [
+        {
+          "mois": "2021-11",
+          "quantite": 1,
+        },
+      ]
+    `)
+
+    await knex.raw(
+      `INSERT INTO public.journaux (id, utilisateur_id, date, element_id, operation, titre_id) VALUES ('${idGenerate()}', '${
+        user.id
+      }', '2021-11-10 09:02:19.012000 +00:00', '${idGenerate()}', 'update', '${titre.id}')`
+    )
+    tested = await getTitresModifiesByMonth(dbPool)
+    expect(tested).toMatchInlineSnapshot(`
+      [
+        {
+          "mois": "2021-11",
+          "quantite": 2,
+        },
+      ]
+    `)
+  })
+})
diff --git a/packages/api/src/database/models/caches.ts b/packages/api/src/database/models/caches.ts
deleted file mode 100644
index 4c17e6149127df47b9a8e5d1abb2017e8f5394dc..0000000000000000000000000000000000000000
--- a/packages/api/src/database/models/caches.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import { Model } from 'objection'
-
-import { ICache } from '../../types.js'
-
-interface Caches extends ICache {}
-
-class Caches extends Model {
-  public static tableName = 'caches'
-
-  public static jsonSchema = {
-    type: 'object',
-    required: ['id'],
-
-    properties: {
-      id: { type: 'string', maxLength: 128 },
-      valeur: { type: 'object' },
-    },
-  }
-}
-
-export { Caches }
diff --git a/packages/api/src/database/queries/caches.ts b/packages/api/src/database/queries/caches.ts
deleted file mode 100644
index 7cfafa9f3a67ed91f17a2ff63d957fee2a58733e..0000000000000000000000000000000000000000
--- a/packages/api/src/database/queries/caches.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import { ICache, ICacheId } from '../../types.js'
-
-import { Caches } from '../models/caches.js'
-
-const cacheGet = async (id: ICacheId) => Caches.query().findById(id)
-
-const cacheUpsert = async (cache: ICache) => Caches.query().upsertGraph(cache, { insertMissing: true })
-
-export { cacheGet, cacheUpsert }
diff --git a/packages/api/src/knex/migrations/20240219143213_delete_cache.ts b/packages/api/src/knex/migrations/20240219143213_delete_cache.ts
new file mode 100644
index 0000000000000000000000000000000000000000..6eb71d1034b5cf24fb03781934a53a797b6a3a59
--- /dev/null
+++ b/packages/api/src/knex/migrations/20240219143213_delete_cache.ts
@@ -0,0 +1,7 @@
+import { Knex } from 'knex'
+
+export const up = async (knex: Knex) => {
+  return knex.schema.dropTable('caches')
+}
+
+export const down = () => ({})
diff --git a/packages/api/src/scripts/daily.ts b/packages/api/src/scripts/daily.ts
index 05357b66a10c6f4a58ceaed87855e068a0825355..9f58a40dbaefcd28f4c6f9b4b28f407f9f89d975 100644
--- a/packages/api/src/scripts/daily.ts
+++ b/packages/api/src/scripts/daily.ts
@@ -1,7 +1,6 @@
 import '../init.js'
 import { daily } from '../business/daily.js'
 import { documentsCheck } from '../tools/documents/check.js'
-import { matomoCacheInit } from '../tools/api-matomo/index.js'
 import { consoleOverride } from '../config/logger.js'
 import { mailjetSend } from '../tools/api-mailjet/emails.js'
 import { readFileSync, writeFileSync, createWriteStream } from 'fs'
@@ -36,7 +35,6 @@ const tasks = async () => {
     if (process.env.CAMINO_STAGE) {
       await documentsClean(pool)
       await documentsCheck(pool)
-      await matomoCacheInit()
     }
   } catch (e) {
     console.error('Erreur durant le daily', e)
diff --git a/packages/api/src/tools/api-matomo/index.test.ts b/packages/api/src/tools/api-matomo/index.test.ts
deleted file mode 100644
index f860a67ee135520aa7a7567a07865b6fd5718af8..0000000000000000000000000000000000000000
--- a/packages/api/src/tools/api-matomo/index.test.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import { timeFormat } from './index.js'
-import { describe, expect, test } from 'vitest'
-
-describe('timeFormat', () => {
-  test('conversion', () => {
-    expect(timeFormat('9 min 47s')).toBe(9)
-    expect(timeFormat('47s')).toBe(0)
-  })
-})
diff --git a/packages/api/src/tools/api-matomo/index.ts b/packages/api/src/tools/api-matomo/index.ts
deleted file mode 100644
index ff05cd6eea0e87e1e9f661f87a8079771025da8a..0000000000000000000000000000000000000000
--- a/packages/api/src/tools/api-matomo/index.ts
+++ /dev/null
@@ -1,245 +0,0 @@
-import { cacheGet, cacheUpsert } from '../../database/queries/caches.js'
-import { Statistiques } from 'camino-common/src/statistiques.js'
-
-interface IMatomoSectionData {
-  label: string
-  subtable?: {
-    label: string
-    nb_events: number
-  }[]
-  nb_events: number
-}
-
-interface IMatomoResult {
-  [month: string]: {
-    nb_searches: number
-    nb_actions_per_visit: number
-    avg_time_on_site: string
-    nb_downloads: number
-    label: string
-    subtable: []
-  }
-}
-
-type IMatomoCache = Pick<Statistiques, 'recherches' | 'titresModifies' | 'actions' | 'sessionDuree' | 'telechargements' | 'signalements' | 'reutilisations'>
-
-const matomoMainDataGet = async (duree: number) => {
-  // Datas de la page 'Récapitulatif' des visites dans matomo
-  // url
-  const pathVisit = getPath('API.get', 'month', {
-    date: `previous${duree}`,
-    format_metrics: 1,
-  })
-
-  // Matomo retourne un objet dont
-  // les clés sont les mois,
-  // les valeurs sont des objets dont les clés utiles aux stats sont
-  // nb_searches : nombre de recherches (int)
-  // nb_actions_per_visit : nombre moyen d'actions (int)
-  // avg_time_on_site : temps de session moyen (string)
-  // nb_downloads : nombre de téléchargements
-  const response = await fetch(pathVisit)
-  const matomoVisitData: IMatomoResult = (await response.json()) as IMatomoResult
-
-  // Les clés de l’objet sont les mois { "2020-09": ...,}
-  const monthsArray = Object.keys(matomoVisitData)
-
-  // objet mois:nbr de recherches
-  const recherches = monthsArray.map(key => {
-    return {
-      mois: key,
-      quantite: matomoVisitData[key].nb_searches || 0,
-    }
-  })
-
-  // données du dernier mois
-  const dataCurrent = matomoVisitData[monthsArray[monthsArray.length - 1]]
-
-  // nombre d'action du dernier mois
-  const actions = dataCurrent.nb_actions_per_visit ? dataCurrent.nb_actions_per_visit : 0
-  // temps de session du dernier mois
-  const sessionDuree = timeFormat(dataCurrent.avg_time_on_site)
-  // nombre de téléchargements du dernier mois
-  const telechargements = dataCurrent.nb_downloads ? dataCurrent.nb_downloads : 0
-
-  return { recherches, actions, sessionDuree, telechargements }
-}
-
-const nbEventsByLabelGet = async (label: string): Promise<number> => {
-  const tomorrowDate = new Date()
-  tomorrowDate.setDate(tomorrowDate.getDate() + 1)
-
-  // ces évenements ont débuté à partir de 2020
-  const pathVisit = getPath('Events.getAction', 'range', {
-    date: `2020-01-01,${tomorrowDate.toISOString().slice(0, 10)}`,
-    label,
-  })
-
-  const response = await fetch(pathVisit)
-  const matomoVisitData: IMatomoSectionData[] = (await response.json()) as IMatomoSectionData[]
-
-  return matomoVisitData.length > 0 ? matomoVisitData[0].nb_events : 0
-}
-
-const erreursSignaleesCountGet = async () => {
-  const nbEvents = await nbEventsByLabelGet('titre-erreur_signaler')
-
-  // historiquement il y a déjà eu 150 erreurs signalées et 4 erreurs avec un ancien label
-  return 150 + 4 + nbEvents
-}
-
-const reutilisationsCountGet = async () => {
-  const nbEvents = await nbEventsByLabelGet('titres-flux-geojson')
-
-  // historiquement il y a déjà eu 6 réutilisations
-  return 6 + nbEvents
-}
-
-const nbEventsBySectionGet = (monthData: IMatomoSectionData, month: string): number => {
-  // Datas des évènements, catégorie 'titres-sections', actions:
-  // titre-editer
-  // titre-demarche_ajouter
-  // titre-demarche_editer
-  // titre-demarche_supprimer
-  // titre-etape_ajouter
-  // titre-etape_editer
-  // titre-etape_supprimer
-  // titre-etape-doc_ajouter
-  // jusqu'au 01/10/2020
-  // et
-  // titre-xxx-enregistrer
-  // à partir du 01/10/2020
-  const toggleDate = new Date(2020, 9, 1)
-
-  const eventOldActionsArray = [
-    'titre-editer',
-    'titre-demarche_ajouter',
-    'titre-demarche_editer',
-    'titre-demarche_supprimer',
-    'titre-etape_ajouter',
-    'titre-etape_editer',
-    'titre-etape_supprimer',
-    'titre-etape-doc_ajouter',
-  ]
-
-  //                           titre-                      |  commence par : titre-
-  //                                 [    ]                |  matche les caractères qui sont...
-  //                                  a-z                  |  ...ou bien une lettre minuscule
-  //                                     -                 |  ...ou bien un tiret
-  //                                       *               |  0 ou n fois
-  //                                        enregistrer    |  termine par : enregistrer
-  const eventNewActionRegex = /titre-[a-z-]*enregistrer/g
-
-  if (monthData.label === 'titre-sections') {
-    return monthData.subtable!.reduce(
-      (
-        nbEventsByAction: number,
-        eventAction: {
-          label: string
-          nb_events: number
-        }
-      ) => {
-        if (Date.parse(month) < Date.parse(toggleDate.toString())) {
-          if (eventOldActionsArray.includes(eventAction.label)) {
-            nbEventsByAction += eventAction.nb_events
-          }
-        } else if (eventAction.label.match(eventNewActionRegex)) {
-          nbEventsByAction += eventAction.nb_events
-        }
-
-        return nbEventsByAction
-      },
-      0
-    )
-  }
-
-  return 0
-}
-const titresModifiesCountGet = async (duree: number) => {
-  const pathVisit = getPath('Events.getCategory', 'month', {
-    date: `previous${duree}`,
-  })
-  const response = await fetch(pathVisit)
-  const matomoVisitData: any = await response.json()
-
-  // Retourne un tableau par mois
-  return Object.keys(matomoVisitData).reduce((acc: { mois: string; quantite: number }[], month) => {
-    const monthDataArray = matomoVisitData[month] as IMatomoSectionData[]
-
-    if (!monthDataArray) {
-      acc.push({ mois: month, quantite: 0 })
-
-      return acc
-    }
-
-    const nbEvents = monthDataArray.reduce((nbEventsByMonth, monthData) => {
-      const nbEventsBySection = nbEventsBySectionGet(monthData, month)
-
-      return nbEventsByMonth + nbEventsBySection
-    }, 0)
-
-    acc.push({ mois: month, quantite: nbEvents })
-
-    return acc
-  }, [])
-}
-
-export const matomoCacheInit = async () => {
-  console.info()
-  console.info('- - -')
-  console.info('rafraichissement du cache Matomo…')
-  // nombre de mois pour lesquels on souhaite des stats
-  const duree = 12
-
-  const matomoResults = await Promise.all([matomoMainDataGet(duree), erreursSignaleesCountGet(), reutilisationsCountGet(), titresModifiesCountGet(duree)])
-  const { recherches, actions, sessionDuree, telechargements } = matomoResults[0]
-
-  // nombre d'erreurs signalées
-  const signalements = matomoResults[1]
-
-  // nombre de réutilisations
-  const reutilisations = matomoResults[2]
-
-  const titresModifies = matomoResults[3]
-
-  const matomoCacheValue: IMatomoCache = {
-    recherches,
-    titresModifies,
-    actions,
-    sessionDuree,
-    telechargements,
-    signalements,
-    reutilisations,
-  }
-
-  await cacheUpsert({
-    id: 'matomo',
-    valeur: matomoCacheValue,
-  })
-
-  return matomoCacheValue
-}
-
-export const matomoData = async () => {
-  const matomoCache = await cacheGet('matomo')
-
-  if (!matomoCache) {
-    return matomoCacheInit()
-  }
-
-  return matomoCache.valeur as IMatomoCache
-}
-
-export const timeFormat = (time: string) => {
-  // si le temps ne présente que des secondes, l'afficher ainsi
-  // sinon, ne garder que les minutes
-  const index = time.search('min')
-
-  return index === -1 ? 0 : Number.parseInt(time.substring(0, index).replace(' ', ''), 10)
-}
-
-const getPath = (method: string, period: string, params?: { [param: string]: string | number }) => {
-  const _params = params ? Object.entries(params).reduce((acc, param) => (acc = `${acc}&${param[0]}=${param[1]}`), '') : ''
-
-  return `${process.env.API_MATOMO_URL}/index.php?expanded=1${_params}&filter_limit=-1&format=JSON&idSite=${process.env.API_MATOMO_ID}&method=${method}&module=API&period=${period}&token_auth=${process.env.API_MATOMO_TOKEN}`
-}
diff --git a/packages/api/src/tools/database-to-json/tables.ts b/packages/api/src/tools/database-to-json/tables.ts
index 36048a6ab539cc300571a2e454fff0633909052b..6cc271262b710263e8a6cb12f292b1fac558abed 100644
--- a/packages/api/src/tools/database-to-json/tables.ts
+++ b/packages/api/src/tools/database-to-json/tables.ts
@@ -1,7 +1,5 @@
 // Liste des noms des tables à sauvegarder au format json
 export const tables = [
-  // la table 'caches' n'est pas utile dans les json
-  // { name: 'caches',orderBy: ['id'] },
   { name: 'communes', orderBy: ['id'] },
   { name: 'documents', orderBy: ['id'] },
   { name: 'entreprises', orderBy: ['id'] },
diff --git a/packages/api/src/tools/matomo.ts b/packages/api/src/tools/matomo.ts
deleted file mode 100644
index cb074879ae1c2466c36f13612dc469939fc3c16a..0000000000000000000000000000000000000000
--- a/packages/api/src/tools/matomo.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-import MatomoTracker from 'matomo-tracker'
-
-export const matomo =
-  process.env.API_MATOMO_ID && Number(process.env.API_MATOMO_ID) && process.env.API_MATOMO_URL
-    ? new MatomoTracker(Number(process.env.API_MATOMO_ID), `${process.env.API_MATOMO_URL}/matomo.php`, false)
-    : null
diff --git a/packages/api/src/types.ts b/packages/api/src/types.ts
index b8ea6513481384d6de95ac51614b96bceb34d0b0..c7bd0bab571af2b6a2e4fe6defd6a1513a00b203 100644
--- a/packages/api/src/types.ts
+++ b/packages/api/src/types.ts
@@ -340,13 +340,6 @@ interface ITitreEtapeFiltre {
   dateFin?: string
 }
 
-type ICacheId = 'matomo'
-
-interface ICache {
-  id: ICacheId
-  valeur: any
-}
-
 interface ITitreType {
   id: TitreTypeId
   domaineId: DomaineId
@@ -482,8 +475,6 @@ export {
   IPropsTitreEtapesIds,
   IHeritageProps,
   IHeritageContenu,
-  ICache,
-  ICacheId,
   IJournaux,
   IDecisionAnnexeContenu,
 }
diff --git a/packages/api/tsconfig.json b/packages/api/tsconfig.json
index 0c15d560565ed0bbfa26e54a5f7c0454204764f4..3f119945251a3eb5aaf6a5b4a452ab4268f5f89f 100644
--- a/packages/api/tsconfig.json
+++ b/packages/api/tsconfig.json
@@ -22,8 +22,7 @@
     "noEmit": true,
     "paths": {
       "graphql-fields": ["./src/@types/graphql-fields"],
-      "html-to-text": ["./src/@types/html-to-text"],
-      "matomo-tracker": ["./src/@types/matomo-tracker"]
+      "html-to-text": ["./src/@types/html-to-text"]
     },
   }
 }
diff --git a/packages/common/src/statistiques.ts b/packages/common/src/statistiques.ts
index 42c555a70649d82a185f6d3dbb95bced3c5dcc86..95f20509fb01a7071feca74109ea6788dcbb3c62 100644
--- a/packages/common/src/statistiques.ts
+++ b/packages/common/src/statistiques.ts
@@ -7,22 +7,21 @@ import { SUBSTANCES_FISCALES_IDS, SubstanceFiscaleId } from './static/substances
 import { TitresTypes } from './static/titresTypes.js'
 import { CaminoStatistiquesDataGouvId } from './static/statistiques.js'
 
-export interface QuantiteParMois {
-  mois: string
-  quantite: number
-}
+export const yearMonthValidator = z
+  .string()
+  .regex(/^\d{4}-\d{2}$/)
+  .brand<'Year-Month'>()
+export const quantitesParMoisValidator = z.object({
+  mois: yearMonthValidator,
+  quantite: z.coerce.number(),
+})
+export type QuantiteParMois = z.infer<typeof quantitesParMoisValidator>
 
 export interface Statistiques {
   titresActivitesBeneficesEntreprise: number
   titresActivitesBeneficesAdministration: number
-  recherches: QuantiteParMois[]
-  titresModifies: QuantiteParMois[]
-  actions: number
-  sessionDuree: number
-  telechargements: number
   demarches: number
-  signalements: number
-  reutilisations: number
+  titresModifies: QuantiteParMois[]
 }
 
 export const substancesFiscalesStats = [
diff --git a/packages/ui/src/app.tsx b/packages/ui/src/app.tsx
index 0de794dc01707541a1ad00f2b8bc015ed1db755a..d746e63968154280a774665be19d8fec2488e5e6 100644
--- a/packages/ui/src/app.tsx
+++ b/packages/ui/src/app.tsx
@@ -2,7 +2,7 @@ import '@gouvfr/dsfr/dist/core/core.module'
 import '@gouvfr/dsfr/dist/component/navigation/navigation.module'
 import '@gouvfr/dsfr/dist/component/tab/tab.module'
 
-import { defineComponent, Transition, computed, inject } from 'vue'
+import { defineComponent, Transition, computed } from 'vue'
 import { Messages } from './components/_ui/messages'
 import { Header } from './components/page/header'
 import { Footer } from './components/page/footer'
@@ -12,12 +12,10 @@ import { IconSprite } from './components/_ui/iconSprite'
 import { CaminoError } from './components/error'
 import { useStore } from 'vuex'
 import { RouterView, useRoute } from 'vue-router'
-import { TrackEventFunction } from '@/utils/matomo'
 import { isNotNullNorUndefined } from 'camino-common/src/typescript-tools'
 export const App = defineComponent({
   setup: () => {
     const store = useStore()
-    const matomo = inject<{ trackEvent: TrackEventFunction } | null>('matomo', null)
     const route = useRoute()
 
     const user = computed(() => store.state.user.element)
@@ -36,26 +34,12 @@ export const App = defineComponent({
 
     const currentMenuSection = computed(() => route.meta?.menuSection)
 
-    if (matomo) {
-      // @ts-ignore
-      matomo.customVariableVisitUser(user)
-      // @ts-ignore
-      matomo.trackPageView()
-    }
-
-    // TODO 2023-03-16 typer l’instance matomo dans un .d.ts
-    const trackEvent: TrackEventFunction = (segment, subSegment, event) => {
-      if (matomo) {
-        matomo.trackEvent(segment, subSegment, event)
-      }
-    }
-
     return () => (
       <div class="page relative">
         <MapPattern />
         <IconSprite />
 
-        <Header user={user.value} currentMenuSection={currentMenuSection.value} trackEvent={trackEvent} routePath={route.fullPath} />
+        <Header user={user.value} currentMenuSection={currentMenuSection.value} routePath={route.fullPath} />
 
         <main class="main" role="main">
           <div class="container">{isNotNullNorUndefined(error.value) ? <CaminoError couleur={error.value.type} message={error.value.value} /> : <>{loaded.value ? <RouterView /> : null}</>}</div>
diff --git a/packages/ui/src/components/_common/downloads.tsx b/packages/ui/src/components/_common/downloads.tsx
index a8216bfde31c63d3ffc094059011f1b35980c733..7f6b13420e5d015df395b26a05c2832adc1284c2 100644
--- a/packages/ui/src/components/_common/downloads.tsx
+++ b/packages/ui/src/components/_common/downloads.tsx
@@ -1,4 +1,4 @@
-import { inject, ref, defineComponent, HTMLAttributes, watch } from 'vue'
+import { ref, defineComponent, HTMLAttributes, watch } from 'vue'
 import { useRoute, RouteLocationNormalized, LocationQuery } from 'vue-router'
 import { DsfrSelect, Item } from '../_ui/dsfr-select'
 import { DownloadRestRoutes, DownloadFormat, CaminoRestParams } from 'camino-common/src/rest'
@@ -7,11 +7,10 @@ import { getDownloadRestRoute } from '@/api/client-rest'
 import { saveAs } from 'file-saver'
 import { DsfrButtonIcon } from '../_ui/dsfr-button'
 
-export const Downloads = defineComponent(<T extends DownloadRestRoutes>(props: Omit<Props<T>, 'route' | 'matomo'>) => {
+export const Downloads = defineComponent(<T extends DownloadRestRoutes>(props: Omit<Props<T>, 'route'>) => {
   const route = useRoute()
-  const matomo = inject('matomo', undefined)
 
-  return () => <PureDownloads {...props} route={route} matomo={matomo} />
+  return () => <PureDownloads {...props} route={route} />
 })
 
 // @ts-ignore waiting for https://github.com/vuejs/core/issues/7833
@@ -24,7 +23,6 @@ export interface Props<T extends DownloadRestRoutes> {
   downloadRoute: T
   params: CaminoRestParams<T>
   route: Pick<RouteLocationNormalized, 'query'>
-  matomo?: { trackLink: (url: string, params: string) => void }
   downloadTitle?: string
 }
 
@@ -75,16 +73,12 @@ export const PureDownloads = defineComponent(<T extends DownloadRestRoutes>(prop
 })
 
 // @ts-ignore waiting for https://github.com/vuejs/core/issues/7833
-PureDownloads.props = ['formats', 'downloadRoute', 'params', 'route', 'matomo', 'id', 'downloadTitle', 'class']
+PureDownloads.props = ['formats', 'downloadRoute', 'params', 'route', 'id', 'downloadTitle', 'class']
 
 async function download<T extends DownloadRestRoutes>(selectedFormat: DownloadFormat | null, query: LocationQuery, props: Omit<Props<T>, 'formats' | 'route'>) {
   if (selectedFormat !== null) {
     const url = getDownloadRestRoute(props.downloadRoute, props.params, { format: selectedFormat, ...query })
 
     saveAs(url)
-
-    if (props.matomo) {
-      props.matomo.trackLink(`${window.location.origin}${url}`, 'download')
-    }
   }
 }
diff --git a/packages/ui/src/components/activite-edition.tsx b/packages/ui/src/components/activite-edition.tsx
index 83ada9582efa74e90ac5a67f7c2e1a41b50b9a6a..aab9df8d67e12a51c72947a16305d4133d1259b7 100644
--- a/packages/ui/src/components/activite-edition.tsx
+++ b/packages/ui/src/components/activite-edition.tsx
@@ -1,6 +1,6 @@
 import { ActiviteDocumentsEdit } from './activite/activite-documents-edit'
 import { getPeriode } from 'camino-common/src/static/frequence'
-import { computed, defineComponent, inject, onBeforeUnmount, onMounted, ref } from 'vue'
+import { computed, defineComponent, onBeforeUnmount, onMounted, ref } from 'vue'
 import { AsyncData } from '@/api/client-rest'
 import { Activite, ActiviteDocumentId, ActiviteId, ActiviteIdOrSlug, TempActiviteDocument, activiteIdOrSlugValidator } from 'camino-common/src/activite'
 import { useRouter } from 'vue-router'
@@ -13,10 +13,8 @@ import { SectionsEdit } from './_common/new-sections-edit'
 import { DsfrButton, DsfrLink } from './_ui/dsfr-button'
 import { capitalize } from 'camino-common/src/strings'
 import { Alert } from './_ui/alert'
-import { isNotNullNorUndefined } from 'camino-common/src/typescript-tools'
 
 export const ActiviteEdition = defineComponent(() => {
-  const matomo = inject('matomo', null)
   const router = useRouter()
 
   const activiteId = computed<ActiviteIdOrSlug>(() => {
@@ -25,16 +23,7 @@ export const ActiviteEdition = defineComponent(() => {
 
   return () => (
     <PureActiviteEdition
-      apiClient={{
-        ...apiClient,
-        updateActivite: async (activiteId, activiteTypeId, sectionsWithValue, activiteDocumentIds, newTempDocuments) => {
-          await apiClient.updateActivite(activiteId, activiteTypeId, sectionsWithValue, activiteDocumentIds, newTempDocuments)
-          if (isNotNullNorUndefined(matomo)) {
-            // @ts-ignore
-            matomo.trackEvent('activite', 'activite-enregistrer', ActivitesTypes[activiteTypeId].nom)
-          }
-        },
-      }}
+      apiClient={apiClient}
       goBack={(activiteId: ActiviteId): void => {
         router.push({ name: 'activite', params: { activiteId } })
       }}
diff --git a/packages/ui/src/components/activite/depose-popup.tsx b/packages/ui/src/components/activite/depose-popup.tsx
index 666f0232d3715ba293ef96d00ad45d89a6c5ef16..5a7f928ba84195dd295bf6ecf4da3e87a60ed69d 100644
--- a/packages/ui/src/components/activite/depose-popup.tsx
+++ b/packages/ui/src/components/activite/depose-popup.tsx
@@ -4,7 +4,6 @@ import { ActiviteApiClient } from './activite-api-client'
 import { Activite } from 'camino-common/src/activite'
 import { Alert } from '../_ui/alert'
 import { ActivitesTypes } from 'camino-common/src/static/activitesTypes'
-import { inject } from 'vue'
 
 interface Props {
   close: () => void
@@ -12,8 +11,6 @@ interface Props {
   activite: Pick<Activite, 'id' | 'titre' | 'type_id'>
 }
 export const ActiviteDeposePopup = caminoDefineComponent<Props>(['close', 'apiClient', 'activite'], props => {
-  const matomo = inject('matomo', null)
-
   const content = () => (
     <Alert
       type="warning"
@@ -36,10 +33,6 @@ export const ActiviteDeposePopup = caminoDefineComponent<Props>(['close', 'apiCl
       validate={{
         action: async () => {
           await props.apiClient.deposerActivite(props.activite.id)
-          if (matomo !== null) {
-            // @ts-ignore
-            matomo.trackEvent('titre-activite', 'titre-activite_depot', props.activite.id)
-          }
         },
         text: 'Déposer',
       }}
diff --git a/packages/ui/src/components/document/edit-popup.vue b/packages/ui/src/components/document/edit-popup.vue
index 16a1d48d0a297a8d42d46b552955ca9bfc03a12f..0fd28e402cb6a1b2f0599acd1868117c032df615 100644
--- a/packages/ui/src/components/document/edit-popup.vue
+++ b/packages/ui/src/components/document/edit-popup.vue
@@ -127,12 +127,6 @@ export default {
         route: this.route,
         action: this.action,
       })
-
-      this.eventTrack({
-        categorie: 'titre-sections',
-        action: 'titre-etape-doc-enregistrer',
-        nom: this.document.titreEtapeId,
-      })
     },
 
     cancel() {
@@ -151,12 +145,6 @@ export default {
       }
     },
 
-    eventTrack(event) {
-      if (this.$matomo) {
-        this.$matomo.trackEvent(event.categorie, event.action, event.nom)
-      }
-    },
-
     errorsRemove() {},
   },
 }
diff --git a/packages/ui/src/components/etape-edition.vue b/packages/ui/src/components/etape-edition.vue
index 0d65e27e8aabcfed01a4a52f1d0042b0e4173095..b6c31df70c30d33d166ca637a1bb03f558d392bf 100644
--- a/packages/ui/src/components/etape-edition.vue
+++ b/packages/ui/src/components/etape-edition.vue
@@ -261,12 +261,6 @@ export default {
           if (reroute) {
             await this.reroute(titreEtapeId)
           }
-
-          this.eventTrack({
-            categorie: 'titre-etape',
-            action: 'titre-etape-enregistrer',
-            nom: titreEtapeId,
-          })
         }
         return titreEtapeId
       }
@@ -285,11 +279,6 @@ export default {
               etapeId,
               onDepotDone: async () => {
                 await this.reroute(etapeId)
-                this.eventTrack({
-                  categorie: 'titre-etape',
-                  action: 'titre-etape_depot',
-                  nom: this.$route.params.id,
-                })
               },
             },
           })
@@ -297,12 +286,6 @@ export default {
       }
     },
 
-    eventTrack(event) {
-      if (this.$matomo) {
-        this.$matomo.trackEvent(event.categorie, event.action, event.nom)
-      }
-    },
-
     keyUp(e) {
       if ((e.which || e.keyCode) === 13 && this.complete && !this.isPopupOpen) {
         if (this.dateIsVisible && this.newDate) {
diff --git a/packages/ui/src/components/page/header.stories.tsx b/packages/ui/src/components/page/header.stories.tsx
index 3b0d918558df843a1273b3ee82654639c5811d1c..ea36b846e594e9b8e70f0cc340d8f90eaa148f3f 100644
--- a/packages/ui/src/components/page/header.stories.tsx
+++ b/packages/ui/src/components/page/header.stories.tsx
@@ -26,24 +26,20 @@ const meta: Meta = {
 }
 export default meta
 
-export const Super: StoryFn = () => <Header trackEvent={() => ({})} currentMenuSection={'utilisateurs'} user={{ ...testBlankUser, role: 'super' }} routePath="/titres?domainesIds=['m']" />
+export const Super: StoryFn = () => <Header currentMenuSection={'utilisateurs'} user={{ ...testBlankUser, role: 'super' }} routePath="/titres?domainesIds=['m']" />
 export const AdminONF: StoryFn = () => (
-  <Header trackEvent={() => ({})} currentMenuSection={'utilisateurs'} user={{ ...testBlankUser, role: 'admin', administrationId: 'ope-onf-973-01' }} routePath="/titres?domainesIds=['m']" />
+  <Header currentMenuSection={'utilisateurs'} user={{ ...testBlankUser, role: 'admin', administrationId: 'ope-onf-973-01' }} routePath="/titres?domainesIds=['m']" />
 )
 export const AdminDGTM: StoryFn = () => (
-  <Header trackEvent={() => ({})} currentMenuSection={'utilisateurs'} user={{ ...testBlankUser, role: 'admin', administrationId: 'dea-guyane-01' }} routePath="/titres?domainesIds=['m']" />
+  <Header currentMenuSection={'utilisateurs'} user={{ ...testBlankUser, role: 'admin', administrationId: 'dea-guyane-01' }} routePath="/titres?domainesIds=['m']" />
 )
 export const Editeur: StoryFn = () => (
-  <Header trackEvent={() => ({})} currentMenuSection={'utilisateurs'} user={{ ...testBlankUser, role: 'editeur', administrationId: 'ope-onf-973-01' }} routePath="/titres?domainesIds=['m']" />
+  <Header currentMenuSection={'utilisateurs'} user={{ ...testBlankUser, role: 'editeur', administrationId: 'ope-onf-973-01' }} routePath="/titres?domainesIds=['m']" />
 )
 export const Lecteur: StoryFn = () => (
-  <Header trackEvent={() => ({})} currentMenuSection={'utilisateurs'} user={{ ...testBlankUser, role: 'lecteur', administrationId: 'ope-onf-973-01' }} routePath="/titres?domainesIds=['m']" />
+  <Header currentMenuSection={'utilisateurs'} user={{ ...testBlankUser, role: 'lecteur', administrationId: 'ope-onf-973-01' }} routePath="/titres?domainesIds=['m']" />
 )
-export const Entreprise: StoryFn = () => (
-  <Header trackEvent={() => ({})} currentMenuSection={'utilisateurs'} user={{ ...testBlankUser, role: 'entreprise', entreprises: [] }} routePath="/titres?domainesIds=['m']" />
-)
-export const BureauDEtudes: StoryFn = () => (
-  <Header trackEvent={() => ({})} currentMenuSection={'utilisateurs'} user={{ ...testBlankUser, role: 'bureau d’études', entreprises: [] }} routePath="/titres?domainesIds=['m']" />
-)
-export const Defaut: StoryFn = () => <Header trackEvent={() => ({})} currentMenuSection={'utilisateurs'} user={{ ...testBlankUser, role: 'defaut' }} routePath="/titres?domainesIds=['m']" />
-export const Deconnecte: StoryFn = () => <Header trackEvent={() => ({})} currentMenuSection={'utilisateurs'} user={undefined} routePath="/titres?domainesIds=['m']" />
+export const Entreprise: StoryFn = () => <Header currentMenuSection={'utilisateurs'} user={{ ...testBlankUser, role: 'entreprise', entreprises: [] }} routePath="/titres?domainesIds=['m']" />
+export const BureauDEtudes: StoryFn = () => <Header currentMenuSection={'utilisateurs'} user={{ ...testBlankUser, role: 'bureau d’études', entreprises: [] }} routePath="/titres?domainesIds=['m']" />
+export const Defaut: StoryFn = () => <Header currentMenuSection={'utilisateurs'} user={{ ...testBlankUser, role: 'defaut' }} routePath="/titres?domainesIds=['m']" />
+export const Deconnecte: StoryFn = () => <Header currentMenuSection={'utilisateurs'} user={undefined} routePath="/titres?domainesIds=['m']" />
diff --git a/packages/ui/src/components/page/header.tsx b/packages/ui/src/components/page/header.tsx
index 1ac8190d502aaa36616be94f4d552a7899021a31..9be0c37e3586c248630c48a0c9e273417361b2d3 100644
--- a/packages/ui/src/components/page/header.tsx
+++ b/packages/ui/src/components/page/header.tsx
@@ -3,14 +3,13 @@ import { Role, User } from 'camino-common/src/roles'
 import { canReadActivites } from 'camino-common/src/permissions/activites'
 import { QuickAccessTitre } from '@/components/page/quick-access-titre'
 import { caminoDefineComponent } from '@/utils/vue-tsx-utils'
-import { MenuSection, TrackEventFunction } from '@/utils/matomo'
 import { DsfrButtonIcon } from '../_ui/dsfr-button'
 import { isNotNullNorUndefinedNorEmpty } from 'camino-common/src/typescript-tools'
+import { MenuSection } from '../../router'
 
 interface Props {
   user: User
   currentMenuSection: MenuSection | null
-  trackEvent: TrackEventFunction
   routePath: string
 }
 
@@ -34,18 +33,10 @@ const isDirectLink = (link: Link | LinkList): link is Link => Object.prototype.h
 
 const ANNUAIRE = { label: 'Annuaire', sublinks: [links.ENTREPRISES, links.ADMINISTRATIONS, links.UTILISATEURS] }
 
-const HeaderLinks: FunctionalComponent<Pick<Props, 'user' | 'trackEvent' | 'routePath'> & { userLinkClicked: () => void }> = props => {
+const HeaderLinks: FunctionalComponent<Pick<Props, 'user' | 'routePath'> & { userLinkClicked: () => void }> = props => {
   const loginUrl = '/oauth2/sign_in?rd=' + encodeURIComponent(`${window.location.origin}${props.routePath}`)
   const logoutUrl = '/apiUrl/deconnecter'
 
-  const logout = () => {
-    props.trackEvent('menu-utilisateur', 'menu-utilisateur', 'deconnexion')
-  }
-
-  const login = () => {
-    props.trackEvent('menu', 'bouton', 'utilisateur')
-  }
-
   return (
     <div class="fr-btns-group">
       {props.user ? (
@@ -56,14 +47,14 @@ const HeaderLinks: FunctionalComponent<Pick<Props, 'user' | 'trackEvent' | 'rout
             </router-link>
           </div>
           <div>
-            <a class="fr-btn fr-icon-lock-line" href={logoutUrl} onClick={logout}>
+            <a class="fr-btn fr-icon-lock-line" href={logoutUrl}>
               Se déconnecter
             </a>
           </div>
         </>
       ) : (
         <div>
-          <a class="fr-btn fr-icon-lock-fill" href={loginUrl} onClick={login}>
+          <a class="fr-btn fr-icon-lock-fill" href={loginUrl}>
             Se connecter / S’enregistrer
           </a>
         </div>
@@ -72,7 +63,7 @@ const HeaderLinks: FunctionalComponent<Pick<Props, 'user' | 'trackEvent' | 'rout
   )
 }
 
-export const Header = caminoDefineComponent<Props>(['user', 'currentMenuSection', 'trackEvent', 'routePath'], props => {
+export const Header = caminoDefineComponent<Props>(['user', 'currentMenuSection', 'routePath'], props => {
   const getAriaCurrent = (link: LinkList): { 'aria-current'?: true } => (link.sublinks.some(({ path }) => path === props.currentMenuSection) ? { 'aria-current': true } : {})
 
   const getAriaPage = (link: Link): { 'aria-current'?: 'page' } => {
@@ -94,15 +85,12 @@ export const Header = caminoDefineComponent<Props>(['user', 'currentMenuSection'
   const searchModalId = 'headerSearchModalId'
   const navigationId = 'headerNavigationId'
 
-  const linkClick = (path: Link['path']) => {
+  const linkClick = () => {
     // On ferme la modale
     modalMenuOpened.value = false
-    if (path !== 'journaux') {
-      props.trackEvent('menu-sections', 'menu-section', path)
-    }
   }
 
-  const sublinkClick = (path: Link['path']) => {
+  const sublinkClick = () => {
     // On ferme le menu déroulant d’annuaire
     const navigationElement = document.getElementById(navigationId)
     if (navigationElement) {
@@ -111,7 +99,7 @@ export const Header = caminoDefineComponent<Props>(['user', 'currentMenuSection'
         members[0].conceal()
       }
     }
-    linkClick(path)
+    linkClick()
   }
   const linksByRole = computed<Record<Role, (Link | LinkList)[]>>(() => {
     const linkActivites = canReadActivites(props.user) ? [links.ACTIVITES] : []
@@ -176,7 +164,7 @@ export const Header = caminoDefineComponent<Props>(['user', 'currentMenuSection'
               </div>
               <div class="fr-header__tools">
                 <div class="fr-header__tools-links">
-                  <HeaderLinks user={props.user} trackEvent={props.trackEvent} routePath={props.routePath} userLinkClicked={closeModals} />
+                  <HeaderLinks user={props.user} routePath={props.routePath} userLinkClicked={closeModals} />
                 </div>
                 <div class={`fr-header__search fr-modal ${modalSearchOpened.value ? 'fr-modal--opened' : ''}`} id={searchModalId} aria-labelledby="button-search" aria-label="Recherche dans le site">
                   <div class="fr-container">
@@ -208,14 +196,14 @@ export const Header = caminoDefineComponent<Props>(['user', 'currentMenuSection'
               class="fr-btn--close"
             />
             <div class="fr-header__menu-links">
-              <HeaderLinks user={props.user} trackEvent={props.trackEvent} routePath={props.routePath} userLinkClicked={closeModals} />
+              <HeaderLinks user={props.user} routePath={props.routePath} userLinkClicked={closeModals} />
             </div>
             <nav class="fr-nav" id={navigationId} role="navigation" aria-label="Menu principal">
               <ul class="fr-nav__list">
                 {linksByRole.value[props.user?.role ?? 'defaut'].map((link, index) => (
                   <li key={link.label} class="fr-nav__item">
                     {isDirectLink(link) ? (
-                      <router-link class="fr-nav__link" to={{ name: link.path }} target="_self" onClick={() => linkClick(link.path)} {...getAriaPage(link)}>
+                      <router-link class="fr-nav__link" to={{ name: link.path }} target="_self" onClick={linkClick} {...getAriaPage(link)}>
                         {link.label}
                       </router-link>
                     ) : (
@@ -227,7 +215,7 @@ export const Header = caminoDefineComponent<Props>(['user', 'currentMenuSection'
                           <ul class="fr-menu__list">
                             {link.sublinks.map((sublink, subIndex) => (
                               <li key={sublink.label}>
-                                <router-link onClick={() => sublinkClick(sublink.path)} class="fr-nav__link" to={{ name: sublink.path }} target="_self" id={`nav-${index}-${subIndex}`}>
+                                <router-link onClick={sublinkClick} class="fr-nav__link" to={{ name: sublink.path }} target="_self" id={`nav-${index}-${subIndex}`}>
                                   {sublink.label}
                                 </router-link>
                               </li>
diff --git a/packages/ui/src/components/page/quick-access-titre.tsx b/packages/ui/src/components/page/quick-access-titre.tsx
index 79695772d962351fb70314300098cde687b8829f..9ee84c34362bec70759dd3d125deeff6b579feb1 100644
--- a/packages/ui/src/components/page/quick-access-titre.tsx
+++ b/packages/ui/src/components/page/quick-access-titre.tsx
@@ -3,7 +3,7 @@ import { TitresTypesTypes } from 'camino-common/src/static/titresTypesTypes'
 import { getDomaineId, getTitreTypeType } from 'camino-common/src/static/titresTypes'
 import { titresRechercherByReferences } from '@/api/titres'
 import { useRouter } from 'vue-router'
-import { ref, inject, FunctionalComponent } from 'vue'
+import { ref, FunctionalComponent } from 'vue'
 import { caminoDefineComponent } from '@/utils/vue-tsx-utils'
 import { titreApiClient, TitreForTitresRerchercherByNom } from '../titre/titre-api-client'
 import { capitalize } from 'camino-common/src/strings'
@@ -15,7 +15,6 @@ export const QuickAccessTitre = caminoDefineComponent<{ id: string; onSelectTitr
   const router = useRouter()
   const titres = ref<TitreForTitresRerchercherByNom[]>([])
 
-  const matomo = inject('matomo', null)
   const search = async (searchTerm: string): Promise<void> => {
     const intervalle = 10
 
@@ -32,10 +31,6 @@ export const QuickAccessTitre = caminoDefineComponent<{ id: string; onSelectTitr
 
   const onSelectedTitre = (titre: TitreForTitresRerchercherByNom | undefined) => {
     if (titre) {
-      if (isNotNullNorUndefined(matomo)) {
-        // @ts-ignore
-        matomo.trackEvent('navigation', 'navigation-rapide', titre.id)
-      }
       router.push({ name: 'titre', params: { id: titre.id } })
       props.onSelectTitre()
     }
diff --git a/packages/ui/src/components/statistiques.tsx b/packages/ui/src/components/statistiques.tsx
index af3cef00f2f2ec6101516ef9de3491c09b8cf1ac..b8602ec951680fcede87a2a1df899344be1a0573 100644
--- a/packages/ui/src/components/statistiques.tsx
+++ b/packages/ui/src/components/statistiques.tsx
@@ -1,4 +1,4 @@
-import { defineComponent, inject, onMounted } from 'vue'
+import { defineComponent, onMounted } from 'vue'
 import { Tab, Tabs } from './_ui/tabs'
 import { useRoute, useRouter, RouterView } from 'vue-router'
 import { NonEmptyArray, getEntriesHardcore } from 'camino-common/src/typescript-tools'
@@ -35,14 +35,8 @@ type TabId = keyof typeof routeToTab
 export const Statistiques = defineComponent(() => {
   const route = useRoute()
   const router = useRouter()
-  const matomo = inject('matomo', null)
 
   onMounted(() => {
-    if (matomo) {
-      // @ts-ignore
-      matomo.trackEvent('menu-sections', 'menu-section', 'statistiques')
-    }
-
     if (route.name === 'statistiques') {
       router.replace({ name: 'statistiques-globales' })
     }
diff --git a/packages/ui/src/components/statistiques/globales.stories.tsx b/packages/ui/src/components/statistiques/globales.stories.tsx
index 2920f7a450503cbc4e517fbf178c7d12f98f2e15..4e06814d7a4b6576beaae3e734fb6c678ba4016a 100644
--- a/packages/ui/src/components/statistiques/globales.stories.tsx
+++ b/packages/ui/src/components/statistiques/globales.stories.tsx
@@ -1,3 +1,4 @@
+import { yearMonthValidator } from 'camino-common/src/statistiques'
 import { PureGlobales } from './globales'
 import { Meta, StoryFn } from '@storybook/vue3'
 
@@ -13,40 +14,21 @@ export const DefaultNoSnapshot: StoryFn = () => (
     statistiques={{
       titresActivitesBeneficesEntreprise: 678,
       titresActivitesBeneficesAdministration: 339,
-      recherches: [
-        { mois: '2021-05', quantite: 0 },
-        { mois: '2021-06', quantite: 0 },
-        { mois: '2021-07', quantite: 3657 },
-        { mois: '2021-08', quantite: 2787 },
-        { mois: '2021-09', quantite: 2505 },
-        { mois: '2021-10', quantite: 3905 },
-        { mois: '2021-11', quantite: 4644 },
-        { mois: '2021-12', quantite: 3022 },
-        { mois: '2022-01', quantite: 5358 },
-        { mois: '2022-02', quantite: 5162 },
-        { mois: '2022-03', quantite: 6769 },
-        { mois: '2022-04', quantite: 2612 },
-      ],
       titresModifies: [
-        { mois: '2021-05', quantite: 0 },
-        { mois: '2021-06', quantite: 54 },
-        { mois: '2021-07', quantite: 320 },
-        { mois: '2021-08', quantite: 90 },
-        { mois: '2021-09', quantite: 152 },
-        { mois: '2021-10', quantite: 259 },
-        { mois: '2021-11', quantite: 107 },
-        { mois: '2021-12', quantite: 310 },
-        { mois: '2022-01', quantite: 178 },
-        { mois: '2022-02', quantite: 189 },
-        { mois: '2022-03', quantite: 223 },
-        { mois: '2022-04', quantite: 147 },
+        { mois: yearMonthValidator.parse('2021-05'), quantite: 0 },
+        { mois: yearMonthValidator.parse('2021-06'), quantite: 54 },
+        { mois: yearMonthValidator.parse('2021-07'), quantite: 320 },
+        { mois: yearMonthValidator.parse('2021-08'), quantite: 90 },
+        { mois: yearMonthValidator.parse('2021-09'), quantite: 152 },
+        { mois: yearMonthValidator.parse('2021-10'), quantite: 259 },
+        { mois: yearMonthValidator.parse('2021-11'), quantite: 107 },
+        { mois: yearMonthValidator.parse('2021-12'), quantite: 310 },
+        { mois: yearMonthValidator.parse('2022-01'), quantite: 178 },
+        { mois: yearMonthValidator.parse('2022-02'), quantite: 189 },
+        { mois: yearMonthValidator.parse('2022-03'), quantite: 223 },
+        { mois: yearMonthValidator.parse('2022-04'), quantite: 147 },
       ],
-      actions: 27.6,
-      sessionDuree: 8,
-      telechargements: 139,
       demarches: 366,
-      signalements: 352,
-      reutilisations: 6,
       "Nombre d'utilisateurs rattachés à une Autorité": 5,
       "Nombre d'utilisateurs rattachés à une Dréal": 38,
       "Nombre d'utilisateurs rattachés à une Déal": 8,
diff --git a/packages/ui/src/components/statistiques/globales.tsx b/packages/ui/src/components/statistiques/globales.tsx
index 52581942b89e6b10b706bfcaad84a803e0d6767c..88794fb2229193945dbec86c10fc3b4d13a1aacc 100644
--- a/packages/ui/src/components/statistiques/globales.tsx
+++ b/packages/ui/src/components/statistiques/globales.tsx
@@ -101,10 +101,6 @@ interface Props {
 }
 
 export const PureGlobales: FunctionalComponent<Props> = props => {
-  const recherchesStats = props.statistiques.recherches
-
-  const recherches = recherchesStats[recherchesStats.length - 1].quantite
-
   const utilisateursAdmin =
     props.statistiques["Nombre d'utilisateurs rattachés à un ministère"] +
     props.statistiques["Nombre d'utilisateurs rattachés à une Autorité"] +
@@ -146,40 +142,6 @@ export const PureGlobales: FunctionalComponent<Props> = props => {
 
   return (
     <div>
-      <div id="engagement" class="mb-xxl">
-        <h2 class="mt">Engagement général sur le site</h2>
-        <span class="separator" />
-        <p class="mb-xl">Les données retenues ici témoignent du comportement général des utilisateurs sur le site et de leur engagement auprès du service</p>
-        <div class="tablet-float-blobs clearfix">
-          <div class="tablet-float-blob-1-3">
-            <div class="mb-xl mt">
-              <p class={['fr-display--xs', styles['donnee-importante']]}>{numberFormat(recherches)}</p>
-              <p class="bold text-center">recherches effectuées le mois dernier</p>
-              <p>Le nombre de recherches mensuelles est l'indicateur clé de l'utilisation du service de "cadastre minier"</p>
-            </div>
-
-            <div class="mb-xl">
-              <p class={['fr-display--xs', styles['donnee-importante']]}>{Math.round(props.statistiques.actions)}</p>
-              <p class="bold text-center">nombre moyen d'actions effectuées par utilisateur</p>
-            </div>
-
-            <div class="mb-xl">
-              <p class={['fr-display--xs', styles['donnee-importante']]}>{props.statistiques.sessionDuree} min</p>
-              <p class="bold text-center">temps de session moyen par utilisateur</p>
-            </div>
-          </div>
-          <div class="tablet-float-blob-2-3 mb-xxl">
-            <ConfigurableChart
-              chartConfiguration={lineConfiguration(
-                statsLineFormat({
-                  stats: props.statistiques.recherches,
-                  labelY: 'recherches',
-                })
-              )}
-            />
-          </div>
-        </div>
-      </div>
       <div id="utilisateurs" class="mb-xxl content">
         <h2>Les différents profils des utilisateurs de Camino</h2>
         <span class="separator" />
@@ -247,20 +209,6 @@ export const PureGlobales: FunctionalComponent<Props> = props => {
             />
           </div>
         </div>
-        <div class="desktop-blobs">
-          <div class="desktop-blob-1-3 mb-xl">
-            <p class={['fr-display--xs', styles['donnee-importante']]}>{props.statistiques.telechargements}</p>
-            <p class="bold text-center">téléchargements de pièces relatives à la bonne instruction des titres et autorisations miniers le mois dernier</p>
-          </div>
-          <div class="desktop-blob-1-3 mb-xl">
-            <p class={['fr-display--xs', styles['donnee-importante']]}>{props.statistiques.signalements}</p>
-            <p class="bold text-center">erreurs corrigées sur les bases de données de l'État grâce à la participation des utilisateurs</p>
-          </div>
-          <div class="desktop-blob-1-3 mb-xl">
-            <p class={['fr-display--xs', styles['donnee-importante']]}>{props.statistiques.reutilisations}</p>
-            <p class="bold text-center">réutilisations connues des données ouvertes distribuées</p>
-          </div>
-        </div>
       </div>
 
       <div id="gains" class="mb-xxl">
diff --git a/packages/ui/src/components/titres.tsx b/packages/ui/src/components/titres.tsx
index e792a4cc0ff043409a8eca612b0cd5696df5d788..ccaccc95f4326c609de67896d99c0ad7aa6870de 100644
--- a/packages/ui/src/components/titres.tsx
+++ b/packages/ui/src/components/titres.tsx
@@ -1,4 +1,4 @@
-import { defineComponent, defineAsyncComponent, computed, onMounted, inject, ref } from 'vue'
+import { defineComponent, defineAsyncComponent, computed, onMounted, ref } from 'vue'
 import { useStore } from 'vuex'
 import { User, isAdministration } from 'camino-common/src/roles'
 import { TitreFiltresParams, TitresFiltres, getInitialTitresFiltresParams } from './titres/filtres'
@@ -19,7 +19,6 @@ import { TableRow } from './_ui/table'
 import { titresDownloadFormats } from 'camino-common/src/filters'
 import { TitresStatutIds } from 'camino-common/src/static/titresStatuts'
 import { DemandeTitreButton } from './_common/demande-titre-button'
-import { isNotNullNorUndefined } from 'camino-common/src/typescript-tools'
 
 const defaultFilterByAdministrationUser: Pick<TitreFiltresParams, 'domainesIds' | 'typesIds' | 'statutsIds'> = {
   domainesIds: ['m', 'w', 'g'],
@@ -38,7 +37,6 @@ export const Titres = defineComponent({
 
       return CaminoTitresMap
     })
-    const matomo = inject('matomo', null)
     const store = useStore()
     const router = useRouter()
     const user = computed<User>(() => store.state.user.element)
@@ -222,10 +220,6 @@ export const Titres = defineComponent({
                     paramsForCarte.value = null
                     reloadTitres(newTabId)
                   }
-                  if (isNotNullNorUndefined(matomo)) {
-                    // @ts-ignore
-                    matomo.trackEvent('titres-vue', 'titres-vueId', tabId.value)
-                  }
                 }
               }}
             />
diff --git a/packages/ui/src/components/utilisateur.tsx b/packages/ui/src/components/utilisateur.tsx
index 95acb4e49e1ca913951728f33cd5ffa6343166c8..6efc5207118834a8ffeb9cbc8c61d040a304f1a2 100644
--- a/packages/ui/src/components/utilisateur.tsx
+++ b/packages/ui/src/components/utilisateur.tsx
@@ -1,4 +1,4 @@
-import { computed, defineComponent, inject, onMounted, ref, watch } from 'vue'
+import { computed, defineComponent, onMounted, ref, watch } from 'vue'
 import { Card } from './_ui/card'
 import { User } from 'camino-common/src/roles'
 import { QGisToken } from './utilisateur/qgis-token'
@@ -20,7 +20,6 @@ export const Utilisateur = defineComponent({
     const store = useStore()
     const route = useRoute()
     const router = useRouter()
-    const matomo = inject('matomo', null)
 
     const user = computed<User>(() => {
       return store.state.user.element
@@ -29,10 +28,6 @@ export const Utilisateur = defineComponent({
     const deleteUtilisateur = async (userId: string) => {
       const isMe: boolean = (user.value && userId === user.value.id) ?? false
       if (isMe) {
-        if (matomo) {
-          // @ts-ignore
-          matomo.trackEvent('menu-utilisateur', 'menu-utilisateur', 'deconnexion')
-        }
         // TODO 2023-10-23 type window.location pour s'appuyer sur nos routes rest et pas sur n'importe quoi
         window.location.replace(`/apiUrl/rest/utilisateurs/${userId}/delete`)
       } else {
diff --git a/packages/ui/src/index.ts b/packages/ui/src/index.ts
index aa007d1032075675534489bc230634c185c5c565..ed8e755c3fbf03cc75b488392f64bc7672d1dfc7 100644
--- a/packages/ui/src/index.ts
+++ b/packages/ui/src/index.ts
@@ -4,13 +4,13 @@ import { sync } from 'vuex-router-sync'
 import * as Sentry from '@sentry/vue'
 import { BrowserTracing } from '@sentry/browser'
 
-import VueMatomo from './stats'
 import { App } from './app'
 
 import router from './router'
 import store from './store'
 import { CaminoConfig } from 'camino-common/src/static/config'
 import { getWithJson } from './api/client-rest'
+import { initMatomo } from './stats/matomo'
 // Le Timeout du sse côté backend est mis à 30 secondes, toujours avoir une valeur plus haute ici
 const sseTimeoutInSeconds = 45
 
@@ -82,21 +82,12 @@ Promise.resolve().then(async (): Promise<void> => {
     try {
       if (!configFromJson.matomoHost || !configFromJson.matomoSiteId || !configFromJson.environment) throw new Error('host et/ou siteId manquant(s)')
 
-      const matomo = await VueMatomo({
+      await initMatomo({
         host: configFromJson.matomoHost,
         siteId: configFromJson.matomoSiteId,
         environnement: configFromJson.environment,
         router,
-        store,
-        requireConsent: false,
-        disableCookies: true,
-        trackInitialView: true,
-        trackerFileName: 'piwik',
-        enableHeartBeatTimer: true,
-        enableLinkTracking: true,
       })
-      app.provide('matomo', matomo)
-      app.config.globalProperties.$matomo = matomo
     } catch (e) {
       console.error('erreur : matomo :', e)
     }
diff --git a/packages/ui/src/router/index.ts b/packages/ui/src/router/index.ts
index 4529ca6475a68c675960fa40ba0ca55b97125d0d..d12c826e8ed7ef80ea936e23823711e8b4ef8e52 100644
--- a/packages/ui/src/router/index.ts
+++ b/packages/ui/src/router/index.ts
@@ -1,6 +1,5 @@
 import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'
 import store from '../store'
-import type { MenuSection } from '@/utils/matomo'
 
 import { Dashboard } from '../components/dashboard'
 import { DGTMStatsFull } from '../components/dashboard/dgtm-stats-full'
@@ -126,6 +125,8 @@ const About = async () => {
   return About
 }
 
+export type MenuSection = 'dashboard' | 'titres' | 'demarches' | 'travaux' | 'activites' | 'administrations' | 'entreprises' | 'utilisateurs' | 'metas' | 'statistiques' | 'journaux'
+
 declare module 'vue-router' {
   interface RouteMeta {
     menuSection: MenuSection | null
diff --git a/packages/ui/src/stats/bootstrap.js b/packages/ui/src/stats/bootstrap.js
deleted file mode 100755
index 491bdeb3cc7597213442ecf5763e8b1861e6fedb..0000000000000000000000000000000000000000
--- a/packages/ui/src/stats/bootstrap.js
+++ /dev/null
@@ -1,19 +0,0 @@
-export default function (options) {
-  const { host, trackerFileName } = options
-  const filename = `${host}/${trackerFileName}.js`
-
-  return new Promise((resolve, reject) => {
-    const script = document.createElement('script')
-    script.async = true
-    script.defer = true
-    script.src = filename
-
-    const head = document.head || document.getElementsByTagName('head')[0]
-    head.appendChild(script)
-
-    script.onload = resolve
-    script.onerror = reject
-  }).catch(error => {
-    console.info(`Warning: ${error.target.src}. If the file exists, you may have a tracking blocker enabled.`)
-  })
-}
diff --git a/packages/ui/src/stats/custom-variables.js b/packages/ui/src/stats/custom-variables.js
deleted file mode 100644
index 4e3eb60b54cfa5095e2e6d50130c8e4dbd42618c..0000000000000000000000000000000000000000
--- a/packages/ui/src/stats/custom-variables.js
+++ /dev/null
@@ -1,29 +0,0 @@
-import { isAdministration } from 'camino-common/src/roles'
-
-const visitUser = matomo => user => {
-  if (user) {
-    if (isAdministration(user)) {
-      matomo.setCustomVariable(1, 'administrationId', user.administrationId, 'visit')
-    }
-
-    if (user.entreprises && user.entreprises.length) {
-      user.entreprises.forEach(entreprise => {
-        matomo.setCustomVariable(1, 'entreprisesIds', entreprise.id, 'visit')
-      })
-    }
-
-    if (user.role) {
-      matomo.setCustomVariable(5, 'role', user.role, 'visit')
-    }
-  }
-}
-
-const pageTitre = matomo => titre => {
-  if (titre) {
-    matomo.setCustomVariable(1, 'domaineId', titre.domaine.id, 'page')
-    matomo.setCustomVariable(2, 'typeId', titre.type.typeId, 'page')
-    matomo.setCustomVariable(3, 'statutId', titre.titreStatutId, 'page')
-  }
-}
-
-export { visitUser, pageTitre }
diff --git a/packages/ui/src/stats/index.js b/packages/ui/src/stats/index.js
deleted file mode 100755
index 8675921ecf344c8fb8c8edeb5124ba4c1084e14b..0000000000000000000000000000000000000000
--- a/packages/ui/src/stats/index.js
+++ /dev/null
@@ -1,84 +0,0 @@
-import bootstrap from './bootstrap'
-import { visitUser, pageTitre } from './custom-variables'
-
-const defaultOptions = {
-  requireConsent: false,
-  disableCookies: true,
-  trackInitialView: true,
-  trackerFileName: 'piwik',
-  enableHeartBeatTimer: false,
-  enableLinkTracking: false,
-  heartBeatTimerInterval: 60,
-  environnement: 'dev',
-}
-
-const install = (setupOptions = {}) => {
-  const options = Object.assign({}, defaultOptions, setupOptions)
-
-  return bootstrap(options)
-    .then(() => {
-      const matomo = window.Piwik.getTracker(`${options.host}/${options.trackerFileName}.php`, options.siteId)
-
-      // dimension d'environnement : https://stats.data.gouv.fr/index.php?module=CustomDimensions&action=manage&idSite=70&period=day&date=yesterday#?idDimension=1&scope=visit
-      matomo.setCustomDimension(1, options.environnement)
-      matomo.customVariableVisitUser = visitUser(matomo)
-      matomo.customVariablePageTitre = pageTitre(matomo)
-
-      if (options.requireConsent) {
-        matomo.requireConsent()
-      }
-
-      if (options.enableHeartBeatTimer) {
-        matomo.enableHeartBeatTimer()
-      }
-
-      if (options.disableCookies) {
-        matomo.disableCookies()
-      }
-
-      if (options.enableLinkTracking) {
-        matomo.enableLinkTracking(options.enableLinkTracking)
-        matomo.setDownloadExtensions('csv|odt|xlsx|geojson')
-      }
-
-      if (options.router) {
-        options.router.afterEach((to, from) => {
-          // Unfortunately the window location is not yet updated here
-          // We need to make our own ulr using the data provided by the router
-          const loc = window.location
-
-          // Protocol may or may not contain a colon
-          let protocol = loc.protocol
-          if (protocol.slice(-1) !== ':') {
-            protocol += ':'
-          }
-
-          const url = protocol + '//' + loc.host + to.path
-          matomo.setCustomUrl(url)
-
-          matomo.customVariableVisitUser(options.store.state.user.element)
-          matomo.trackPageView(name)
-
-          if (to.name !== from.name) {
-            // nombre d'affichage de la page
-            // titre, titres, entreprises, activites, demarches, utilisateurs
-            matomo.trackEvent(`page-${to.name}`, `page-${to.name}_acceder`)
-
-            if (to.name === 'titre') {
-              // nombre d'affichage de la page 'titres'
-              let action = `page-titre-from-${from.name}`
-              action += from.query.vue ? `-${from.query.vue}` : ''
-
-              matomo.trackEvent('page-titre', action, to.params.id)
-            }
-          }
-        })
-      }
-      return matomo
-    })
-    .catch(e => {
-      console.error('error during matomo initialization', e)
-    })
-}
-
-export default install
diff --git a/packages/ui/src/stats/matomo.ts b/packages/ui/src/stats/matomo.ts
new file mode 100755
index 0000000000000000000000000000000000000000..4dca711963bef6ee77c2c504bc21d6568910d805
--- /dev/null
+++ b/packages/ui/src/stats/matomo.ts
@@ -0,0 +1,48 @@
+import { isNotNullNorUndefined } from 'camino-common/src/typescript-tools'
+import { Router } from 'vue-router'
+
+export const initMatomo = async (options: { router: Router; host: string; siteId: string; environnement: string }) => {
+  const trackerFileName = 'piwik'
+
+  await bootstrap(options.host, trackerFileName)
+  // @ts-ignore
+  const matomo = window.Piwik.getTracker(`${options.host}/${trackerFileName}.php`, options.siteId)
+
+  // dimension d'environnement : https://stats.data.gouv.fr/index.php?module=CustomDimensions&action=manage&idSite=70&period=day&date=yesterday#?idDimension=1&scope=visit
+  matomo.setCustomDimension(1, options.environnement)
+
+  matomo.enableHeartBeatTimer()
+  matomo.disableCookies()
+  matomo.enableLinkTracking(true)
+  matomo.setDownloadExtensions('csv|odt|xlsx|geojson')
+
+  options.router.afterEach((to, from) => {
+    const url = options.router.resolve(to.fullPath).href
+    const referrerUrl: string | null = isNotNullNorUndefined(from) && isNotNullNorUndefined(from.fullPath) ? options.router.resolve(from.fullPath).href : null
+
+    if (referrerUrl !== null) {
+      matomo.setReferrerUrl(window.location.origin + referrerUrl)
+    }
+    matomo.setCustomUrl(window.location.origin + url)
+    matomo.trackPageView(to.name)
+  })
+}
+
+const bootstrap = (host: string, trackerFileName: string): Promise<unknown> => {
+  const filename = `${host}/${trackerFileName}.js`
+
+  return new Promise((resolve, reject) => {
+    const script = document.createElement('script')
+    script.async = true
+    script.defer = true
+    script.src = filename
+
+    const head = document.head || document.getElementsByTagName('head')[0]
+    head.appendChild(script)
+
+    script.onload = resolve
+    script.onerror = reject
+  }).catch(error => {
+    console.info(`Warning: ${error.target.src}. If the file exists, you may have a tracking blocker enabled.`)
+  })
+}
diff --git a/packages/ui/src/utils/matomo.ts b/packages/ui/src/utils/matomo.ts
deleted file mode 100644
index 92869106a71fdc800ab626c3746530888dd95129..0000000000000000000000000000000000000000
--- a/packages/ui/src/utils/matomo.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-type MatomoSegment = 'menu-utilisateur' | 'menu-sections' | 'menu'
-type MatomoSubsegment = 'menu-utilisateur' | 'menu-section' | 'bouton'
-type MatomoEvent = 'deconnexion' | 'dashboard' | 'titres' | 'demarches' | 'travaux' | 'activites' | 'administrations' | 'entreprises' | 'utilisateurs' | 'metas' | 'utilisateur' | 'statistiques'
-
-const MatomoParams = {
-  'menu-utilisateur': {
-    'menu-utilisateur': ['deconnexion'],
-  },
-  'menu-sections': {
-    'menu-section': ['dashboard', 'titres', 'demarches', 'travaux', 'activites', 'administrations', 'entreprises', 'utilisateurs', 'metas', 'statistiques'],
-  },
-  menu: {
-    bouton: ['utilisateur'],
-  },
-} as const satisfies Record<MatomoSegment, { [key in MatomoSubsegment]?: readonly MatomoEvent[] }>
-
-type MatomoEventParam<T extends MatomoSegment, U extends keyof (typeof MatomoParams)[T]> = Extract<(typeof MatomoParams)[T][U], readonly MatomoEvent[]>[number]
-export type MenuSection = MatomoEventParam<'menu-sections', 'menu-section'> | 'journaux'
-
-// TODO 2023-03-16 typer l’instance matomo dans un .d.ts
-export type TrackEventFunction = <T extends MatomoSegment, U extends keyof (typeof MatomoParams)[T]>(segment: T, subSegment: U, event: MatomoEventParam<T, U>) => void