diff --git a/app.config.environment.alpha.js b/app.config.environment.alpha.js
index 65e8495114766d3cfb68e796f0e39e09bee65a7d..e0c4b0b3eef2dc34174673b70fb38d0e48f04934 100644
--- a/app.config.environment.alpha.js
+++ b/app.config.environment.alpha.js
@@ -17,6 +17,8 @@ module.exports = {
       __DEVELOPMENT__: false,
       __DEVTOOLS__: false,
       __STACK_ASSETS__: target !== 'mobile',
+      __PIWIK_TRACKER_URL__: JSON.stringify('https://statweb.grandlyon.com/'),
+      __PIWIK_SITEID__: 117,
     }),
   ],
   optimization: {
diff --git a/app.config.environment.dev.js b/app.config.environment.dev.js
index 86282e3bca1a3c7ba9ed26ce2c08b0f1842ca3f3..31cbe4a8ce3c192dae0a38450fa5cfafbb4af6aa 100644
--- a/app.config.environment.dev.js
+++ b/app.config.environment.dev.js
@@ -19,7 +19,10 @@ const stackProvidedLibsConfig = {
     new webpack.DefinePlugin({
       'process.env.NODE_ENV': JSON.stringify('development'),
       __IS_ALPHA__: true,
+      __DEVELOPMENT__: true,
       __STACK_ASSETS__: true,
+      __PIWIK_TRACKER_URL__: JSON.stringify('http://localhost:9800/'),
+      __PIWIK_SITEID__: 1,
     }),
   ],
   module: {
diff --git a/app.config.environment.prod.js b/app.config.environment.prod.js
index 9e5401b8d3c62ff9b25fb0316b460c837d9a0452..7dc15dbcfe681d98d64c73b52327f5c51f27a5f1 100644
--- a/app.config.environment.prod.js
+++ b/app.config.environment.prod.js
@@ -17,6 +17,8 @@ module.exports = {
       __DEVELOPMENT__: false,
       __DEVTOOLS__: false,
       __STACK_ASSETS__: target !== 'mobile',
+      __PIWIK_TRACKER_URL__: JSON.stringify('https://statweb.grandlyon.com/'),
+      __PIWIK_SITEID__: 118,
     }),
   ],
   optimization: {
diff --git a/docker/docker-compose.matomo.yml b/docker/docker-compose.matomo.yml
new file mode 100644
index 0000000000000000000000000000000000000000..a0a90254efbabe79f3c8bc443e950f93537fd7e4
--- /dev/null
+++ b/docker/docker-compose.matomo.yml
@@ -0,0 +1,38 @@
+version: '3.8'
+
+services:
+  db:
+    image: mariadb
+    command: --max-allowed-packet=64MB
+    restart: always
+    environment:
+      - MYSQL_ROOT_PASSWORD=root
+      - MYSQL_PASSWORD=password
+      - MYSQL_DATABASE=matomo
+      - MYSQL_USER=matomo
+    volumes:
+      - db:/var/lib/mysql
+
+  app:
+    image: matomo:latest
+    restart: always
+    depends_on:
+      - db
+    environment:
+      - MATOMO_DATABASE_HOST=db
+      - MATOMO_DATABASE_ADAPTER=mysql
+      - MATOMO_DATABASE_TABLES_PREFIX=matomo_
+      - MATOMO_DATABASE_USERNAME=matomo
+      - MATOMO_DATABASE_PASSWORD=password
+      - MATOMO_DATABASE_DBNAME=matomo
+      - PHP_MEMORY_LIMIT=2048M
+    volumes:
+      # - ./config:/var/www/html/config:rw
+      # - ./logs:/var/www/html/logs
+      - matomo:/var/www/html
+    ports:
+      - 9800:80
+
+volumes:
+  db:
+  matomo:
diff --git a/jest.config.js b/jest.config.js
index 6cf339521a29b3096017066df033214ee39a3733..b6a027a5b05f2f8316ff6f26570db8a860f997be 100644
--- a/jest.config.js
+++ b/jest.config.js
@@ -18,6 +18,7 @@ module.exports = {
   globals: {
     __ALLOW_HTTP__: false,
     __TARGET__: 'browser',
+    __PIWIK_TRACKER_URL__: 'http://localhost:9800/',
     cozy: {},
   },
 }
diff --git a/src/components/Action/ActionView.spec.tsx b/src/components/Action/ActionView.spec.tsx
index 8442277f410b7c0b37b595374f43322a2aa542e9..736802cd2e43895ed6c08ca1cf59290f6ea3563c 100644
--- a/src/components/Action/ActionView.spec.tsx
+++ b/src/components/Action/ActionView.spec.tsx
@@ -21,6 +21,9 @@ jest.mock('cozy-ui/transpiled/react/I18n', () => {
     }),
   }
 })
+jest.mock('components/Header/CozyBar', () => 'mock-cozybar')
+jest.mock('components/Header/Header', () => 'mock-header')
+jest.mock('components/Content/Content', () => 'mock-content')
 
 const mockStore = configureStore([])
 describe('ActionView component', () => {
@@ -34,7 +37,7 @@ describe('ActionView component', () => {
     }
     const store = mockStore({
       ecolyo: {
-        challenge: userChallenge,
+        challenge: { currentChallenge: userChallenge },
         global: { ...globalStateData, fluidTypes: [0, 1, 2] },
         profile: profileData,
         modal: modalStateData,
@@ -45,7 +48,7 @@ describe('ActionView component', () => {
         <ActionView />
       </Provider>
     )
-    expect(wrapper.find(ActionChoose).exists())
+    expect(wrapper.find(ActionChoose).exists()).toBeTruthy()
     expect(wrapper).toMatchSnapshot()
   })
   it('should render ActionDone component', () => {
@@ -58,7 +61,7 @@ describe('ActionView component', () => {
     }
     const store = mockStore({
       ecolyo: {
-        challenge: userChallenge,
+        challenge: { currentChallenge: userChallenge },
         global: { ...globalStateData, fluidTypes: [0, 1, 2] },
         profile: profileData,
         modal: modalStateData,
@@ -69,7 +72,7 @@ describe('ActionView component', () => {
         <ActionView />
       </Provider>
     )
-    expect(wrapper.find(ActionDone).exists())
+    expect(wrapper.find(ActionDone).exists()).toBeTruthy()
   })
   it('should render ActionOnGoing component', () => {
     const userChallenge = {
@@ -81,7 +84,7 @@ describe('ActionView component', () => {
     }
     const store = mockStore({
       ecolyo: {
-        challenge: userChallenge,
+        challenge: { currentChallenge: userChallenge },
         global: { ...globalStateData, fluidTypes: [0, 1, 2] },
         modal: modalStateData,
         profile: profileData,
@@ -92,6 +95,6 @@ describe('ActionView component', () => {
         <ActionView />
       </Provider>
     )
-    expect(wrapper.find(ActionOnGoing).exists())
+    expect(wrapper.find(ActionOnGoing).exists()).toBeTruthy()
   })
 })
diff --git a/src/components/Analysis/AnalysisView.spec.tsx b/src/components/Analysis/AnalysisView.spec.tsx
index 286f6cf6b1da754e00ebf01abd88085f258e5790..e3c5062d544c10835394610a6af00cb96ea3e24b 100644
--- a/src/components/Analysis/AnalysisView.spec.tsx
+++ b/src/components/Analysis/AnalysisView.spec.tsx
@@ -1,4 +1,3 @@
-/* eslint-disable react/display-name */
 import React from 'react'
 import { mount } from 'enzyme'
 import * as reactRedux from 'react-redux'
diff --git a/src/components/App.tsx b/src/components/App.tsx
index 86d54f5d42de5d53ecbbe39e9a760de279aea935..3d4fedc312022e6e69d81131d79e268caea5ba6b 100644
--- a/src/components/App.tsx
+++ b/src/components/App.tsx
@@ -1,7 +1,6 @@
 /* eslint-disable @typescript-eslint/no-explicit-any */
-import React from 'react'
+import React, { useEffect } from 'react'
 import { HashRouter } from 'react-router-dom'
-import { createBrowserHistory } from 'history'
 import { Layout, Main, Content } from 'cozy-ui/transpiled/react/Layout'
 import { useSelector } from 'react-redux'
 import { AppStore } from 'store'
@@ -12,14 +11,30 @@ import SplashRoot from 'components/Splash/SplashRoot'
 import SplashScreen from 'components/Splash/SplashScreen'
 import SplashScreenError from 'components/Splash/SplashScreenError'
 import WelcomeModal from 'components/Onboarding/WelcomeModal'
+import MatomoTracker from 'utils/matomoTracker'
+import EnvironmentService from 'services/environment.service'
 
-export const history = createBrowserHistory()
+interface AppProps {
+  tracker: MatomoTracker
+}
 
-export const App = () => {
+export const App = ({ tracker }: AppProps) => {
   const { onboarding, isProfileEcogestureCompleted } = useSelector(
     (state: AppStore) => state.ecolyo.profile
   )
   const { termsStatus } = useSelector((state: AppStore) => state.ecolyo.global)
+  const isDev = new EnvironmentService().isLocal()
+
+  useEffect(() => {
+    if (tracker && !isDev) {
+      if (termsStatus.accepted) {
+        tracker.connectToHistory()
+      }
+      return () => {
+        tracker.disconnectFromHistory()
+      }
+    }
+  }, [termsStatus.accepted, tracker])
 
   return (
     <HashRouter {...history}>
diff --git a/src/components/Challenge/ChallengeView.spec.tsx b/src/components/Challenge/ChallengeView.spec.tsx
index aff70fdae981e3f9fbc59c88497c74ce3c47d6e7..1e33a61329085affa7c19b006327cbb235a5dc19 100644
--- a/src/components/Challenge/ChallengeView.spec.tsx
+++ b/src/components/Challenge/ChallengeView.spec.tsx
@@ -1,8 +1,13 @@
 import React from 'react'
-import { shallow } from 'enzyme'
+import { mount } from 'enzyme'
+import toJson from 'enzyme-to-json'
 import ChallengeView from 'components/Challenge/ChallengeView'
 import * as reactRedux from 'react-redux'
 import { challengeStateDataFull } from '../../../tests/__mocks__/challengeStateData.mock'
+import {
+  createMockStore,
+  mockInitialEcolyoState,
+} from '../../../tests/__mocks__/store'
 
 const mockUseSelector = jest.spyOn(reactRedux, 'useSelector')
 
@@ -16,10 +21,28 @@ jest.mock('cozy-ui/transpiled/react/I18n', () => {
   }
 })
 
+jest.mock('components/Header/CozyBar', () => 'mock-cozybar')
+jest.mock('components/Header/Header', () => 'mock-header')
+jest.mock('components/Content/Content', () => 'mock-content')
+jest.mock('components/Challenge/ChallengeCard', () => 'mock-challengecard')
+
+const useSelectorSpy = jest.spyOn(reactRedux, 'useSelector')
+
 describe('ChallengeView component', () => {
+  // eslint-disable-next-line @typescript-eslint/no-explicit-any
+  let store: any
+  beforeEach(() => {
+    store = createMockStore(mockInitialEcolyoState)
+    useSelectorSpy.mockClear()
+  })
+
   it('should be rendered correctly', () => {
     mockUseSelector.mockReturnValue(challengeStateDataFull)
-    const component = shallow(<ChallengeView />).getElement()
-    expect(component).toMatchSnapshot()
+    const wrapper = mount(
+      <reactRedux.Provider store={store}>
+        <ChallengeView />
+      </reactRedux.Provider>
+    )
+    expect(toJson(wrapper)).toMatchSnapshot()
   })
 })
diff --git a/src/components/Challenge/__snapshots__/ChallengeView.spec.tsx.snap b/src/components/Challenge/__snapshots__/ChallengeView.spec.tsx.snap
index ee1c09130e36abbe633c586977028ea7a54e1e2f..3d17797f4a917add013390c953b6c91c01ebb75e 100644
--- a/src/components/Challenge/__snapshots__/ChallengeView.spec.tsx.snap
+++ b/src/components/Challenge/__snapshots__/ChallengeView.spec.tsx.snap
@@ -1,953 +1,1260 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
 exports[`ChallengeView component should be rendered correctly 1`] = `
-<React.Fragment>
-  <CozyBar
-    titleKey="common.title_challenge"
-  />
-  <Header
-    desktopTitleKey="common.title_challenge"
-    setHeaderHeight={[Function]}
-  />
-  <Content
-    height={0}
-  >
-    <div
-      className="challengeSlider"
-      onClick={[Function]}
-      onMouseDown={[Function]}
-      onMouseMove={[Function]}
-      onMouseUp={[Function]}
-      onTouchEnd={[Function]}
-      onTouchMove={[Function]}
-      onTouchStart={[Function]}
+<Provider
+  store={
+    Object {
+      "clearActions": [Function],
+      "dispatch": [Function],
+      "getActions": [Function],
+      "getState": [Function],
+      "replaceReducer": [Function],
+      "subscribe": [Function],
+    }
+  }
+>
+  <ChallengeView>
+    <mock-cozybar
+      titleKey="common.title_challenge"
+    />
+    <mock-header
+      desktopTitleKey="common.title_challenge"
+      setHeaderHeight={[Function]}
+    />
+    <mock-content
+      height={0}
     >
       <div
-        className="challenge-container"
-        style={
-          Object {
-            "transform": "translateX(16px)",
-          }
-        }
+        className="challengeSlider"
+        onClick={[Function]}
+        onMouseDown={[Function]}
+        onMouseMove={[Function]}
+        onMouseUp={[Function]}
+        onTouchEnd={[Function]}
+        onTouchMove={[Function]}
+        onTouchStart={[Function]}
       >
-        <ChallengeCard
-          cardHeight={384}
-          cardWidth={285}
-          index={0}
-          indexSlider={0}
-          moveToSlide={[Function]}
-          userChallenge={
+        <div
+          className="challenge-container"
+          style={
             Object {
-              "action": Object {
-                "ecogesture": null,
-                "startDate": null,
-                "state": 0,
-              },
-              "description": "Description challenge 1",
-              "duel": Object {
-                "description": "Je parie un ours polaire que vous ne pouvez pas consommer moins que #CONSUMPTION € en 1 semaine",
-                "duration": "P30D",
-                "fluidTypes": Array [],
-                "id": "DUEL001",
-                "startDate": null,
-                "state": 0,
-                "threshold": 0,
-                "title": "Title DUEL001",
-                "userConsumption": 0,
-              },
-              "endingDate": null,
-              "exploration": Object {
-                "complementary_description": "Refaire un tour dans son profil si déjà fait",
-                "date": null,
-                "description": "Avoir complété son profil",
-                "ecogesture_id": "",
-                "fluid_condition": Array [],
-                "id": "EXPLORATION001",
-                "message_success": "Vous avez complété votre profil ou refait un tour dans votre profil",
-                "progress": 0,
-                "state": 0,
-                "target": 1,
-                "type": 1,
-              },
-              "id": "CHALLENGE0001",
-              "progress": Object {
-                "actionProgress": 0,
-                "explorationProgress": 0,
-                "quizProgress": 0,
-              },
-              "quiz": Object {
-                "customQuestion": Object {
-                  "interval": 20,
-                  "period": Object {},
-                  "questionLabel": "Custom1",
-                  "result": 0,
-                  "singleFluid": false,
-                  "timeStep": 20,
-                  "type": 0,
+              "transform": "translateX(-874.2px)",
+            }
+          }
+        >
+          <mock-challengecard
+            cardHeight={384}
+            cardWidth={285}
+            index={0}
+            indexSlider={3}
+            key="0"
+            moveToSlide={[Function]}
+            userChallenge={
+              Object {
+                "action": Object {
+                  "ecogesture": null,
+                  "startDate": null,
+                  "state": 0,
                 },
-                "id": "QUIZ001",
-                "questions": Array [
-                  Object {
-                    "answers": Array [
-                      Object {
-                        "answerLabel": "86 km",
-                        "isTrue": true,
-                      },
-                      Object {
-                        "answerLabel": "78 km",
-                        "isTrue": false,
-                      },
-                      Object {
-                        "answerLabel": "56 km",
-                        "isTrue": false,
-                      },
-                    ],
-                    "explanation": "L’aqueduc du Gier est un des aqueducs antiques de Lyon desservant la ville antique de Lugdunum. Avec ses 86 km il est le plus long des quatre aqueducs ayant alimenté la ville en eau, et celui dont les structures sont le mieux conservées. Il doit son nom au fait qu'il puise aux sources du Gier, affluent du Rhône",
-                    "questionLabel": "Quelle longueur faisait l’aqueduc du Gier pour acheminer l’eau sur Lyon à l’époque romaine ?",
-                    "result": 0,
-                    "source": "string",
-                  },
-                  Object {
-                    "answers": Array [
-                      Object {
-                        "answerLabel": "1 point d’eau public pour 800 habitants.",
-                        "isTrue": true,
-                      },
-                      Object {
-                        "answerLabel": "1 point d’eau public pour 400 habitants.",
-                        "isTrue": false,
-                      },
-                      Object {
-                        "answerLabel": "1 point d’eau public pour 200 habitants.",
-                        "isTrue": false,
-                      },
-                    ],
-                    "explanation": "string",
-                    "questionLabel": "En 1800 à Lyon, combien de points d'eau y avait-il par habitants ?",
-                    "result": 0,
-                    "source": "string",
-                  },
-                  Object {
-                    "answers": Array [
-                      Object {
-                        "answerLabel": "François Mitterrand",
-                        "isTrue": false,
-                      },
-                      Object {
-                        "answerLabel": "Napoléon Ier",
-                        "isTrue": true,
-                      },
-                      Object {
-                        "answerLabel": "Napoléon III",
-                        "isTrue": false,
-                      },
-                    ],
-                    "explanation": "string",
-                    "questionLabel": "Qui officialise la création de la Compagnie Générale des eaux ?",
-                    "result": 0,
-                    "source": "string",
-                  },
-                  Object {
-                    "answers": Array [
-                      Object {
-                        "answerLabel": "string",
-                        "isTrue": false,
-                      },
-                      Object {
-                        "answerLabel": "string",
-                        "isTrue": false,
-                      },
-                      Object {
-                        "answerLabel": "Aristide Dumont",
-                        "isTrue": true,
-                      },
-                    ],
-                    "explanation": "string",
-                    "questionLabel": "Quel ingénieur est à l’origine du projet d’alimentation en eau en 1856 ?",
+                "description": "Description challenge 1",
+                "duel": Object {
+                  "description": "Je parie un ours polaire que vous ne pouvez pas consommer moins que #CONSUMPTION € en 1 semaine",
+                  "duration": "P30D",
+                  "fluidTypes": Array [],
+                  "id": "DUEL001",
+                  "startDate": null,
+                  "state": 0,
+                  "threshold": 0,
+                  "title": "Title DUEL001",
+                  "userConsumption": 0,
+                },
+                "endingDate": null,
+                "exploration": Object {
+                  "complementary_description": "Refaire un tour dans son profil si déjà fait",
+                  "date": null,
+                  "description": "Avoir complété son profil",
+                  "ecogesture_id": "",
+                  "fluid_condition": Array [],
+                  "id": "EXPLORATION001",
+                  "message_success": "Vous avez complété votre profil ou refait un tour dans votre profil",
+                  "progress": 0,
+                  "state": 0,
+                  "target": 1,
+                  "type": 1,
+                },
+                "id": "CHALLENGE0001",
+                "progress": Object {
+                  "actionProgress": 0,
+                  "explorationProgress": 0,
+                  "quizProgress": 0,
+                },
+                "quiz": Object {
+                  "customQuestion": Object {
+                    "interval": 20,
+                    "period": Object {},
+                    "questionLabel": "Custom1",
                     "result": 0,
-                    "source": "string",
+                    "singleFluid": false,
+                    "timeStep": 20,
+                    "type": 0,
                   },
-                ],
-                "result": 0,
+                  "id": "QUIZ001",
+                  "questions": Array [
+                    Object {
+                      "answers": Array [
+                        Object {
+                          "answerLabel": "86 km",
+                          "isTrue": true,
+                        },
+                        Object {
+                          "answerLabel": "78 km",
+                          "isTrue": false,
+                        },
+                        Object {
+                          "answerLabel": "56 km",
+                          "isTrue": false,
+                        },
+                      ],
+                      "explanation": "L’aqueduc du Gier est un des aqueducs antiques de Lyon desservant la ville antique de Lugdunum. Avec ses 86 km il est le plus long des quatre aqueducs ayant alimenté la ville en eau, et celui dont les structures sont le mieux conservées. Il doit son nom au fait qu'il puise aux sources du Gier, affluent du Rhône",
+                      "questionLabel": "Quelle longueur faisait l’aqueduc du Gier pour acheminer l’eau sur Lyon à l’époque romaine ?",
+                      "result": 0,
+                      "source": "string",
+                    },
+                    Object {
+                      "answers": Array [
+                        Object {
+                          "answerLabel": "1 point d’eau public pour 800 habitants.",
+                          "isTrue": true,
+                        },
+                        Object {
+                          "answerLabel": "1 point d’eau public pour 400 habitants.",
+                          "isTrue": false,
+                        },
+                        Object {
+                          "answerLabel": "1 point d’eau public pour 200 habitants.",
+                          "isTrue": false,
+                        },
+                      ],
+                      "explanation": "string",
+                      "questionLabel": "En 1800 à Lyon, combien de points d'eau y avait-il par habitants ?",
+                      "result": 0,
+                      "source": "string",
+                    },
+                    Object {
+                      "answers": Array [
+                        Object {
+                          "answerLabel": "François Mitterrand",
+                          "isTrue": false,
+                        },
+                        Object {
+                          "answerLabel": "Napoléon Ier",
+                          "isTrue": true,
+                        },
+                        Object {
+                          "answerLabel": "Napoléon III",
+                          "isTrue": false,
+                        },
+                      ],
+                      "explanation": "string",
+                      "questionLabel": "Qui officialise la création de la Compagnie Générale des eaux ?",
+                      "result": 0,
+                      "source": "string",
+                    },
+                    Object {
+                      "answers": Array [
+                        Object {
+                          "answerLabel": "string",
+                          "isTrue": false,
+                        },
+                        Object {
+                          "answerLabel": "string",
+                          "isTrue": false,
+                        },
+                        Object {
+                          "answerLabel": "Aristide Dumont",
+                          "isTrue": true,
+                        },
+                      ],
+                      "explanation": "string",
+                      "questionLabel": "Quel ingénieur est à l’origine du projet d’alimentation en eau en 1856 ?",
+                      "result": 0,
+                      "source": "string",
+                    },
+                  ],
+                  "result": 0,
+                  "startDate": null,
+                  "state": 0,
+                },
                 "startDate": null,
-                "state": 0,
-              },
-              "startDate": null,
-              "state": 4,
-              "success": 2,
-              "target": 15,
-              "title": "Challenge 1",
+                "state": 4,
+                "success": 2,
+                "target": 15,
+                "title": "Challenge 1",
+              }
             }
-          }
-        />
-        <ChallengeCard
-          cardHeight={384}
-          cardWidth={285}
-          index={1}
-          indexSlider={0}
-          moveToSlide={[Function]}
-          userChallenge={
-            Object {
-              "action": Object {
-                "ecogesture": null,
-                "startDate": null,
-                "state": 0,
-              },
-              "description": "Description challenge 2",
-              "duel": Object {
-                "description": "Je parie un ours polaire que vous ne pouvez pas consommer moins que #CONSUMPTION € en 1 semaine",
-                "duration": "P30D",
-                "fluidTypes": Array [],
-                "id": "DUEL001",
-                "startDate": null,
-                "state": 0,
-                "threshold": 0,
-                "title": "Title DUEL001",
-                "userConsumption": 0,
-              },
-              "endingDate": null,
-              "exploration": Object {
-                "complementary_description": "Refaire un tour dans son profil si déjà fait",
-                "date": null,
-                "description": "Avoir complété son profil",
-                "ecogesture_id": "",
-                "fluid_condition": Array [],
-                "id": "EXPLORATION001",
-                "message_success": "Vous avez complété votre profil ou refait un tour dans votre profil",
-                "progress": 0,
-                "state": 0,
-                "target": 1,
-                "type": 1,
-              },
-              "id": "CHALLENGE0002",
-              "progress": Object {
-                "actionProgress": 0,
-                "explorationProgress": 0,
-                "quizProgress": 0,
-              },
-              "quiz": Object {
-                "customQuestion": Object {
-                  "interval": 20,
-                  "period": Object {},
-                  "questionLabel": "Custom1",
-                  "result": 0,
-                  "singleFluid": false,
-                  "timeStep": 20,
-                  "type": 0,
+          />
+          <mock-challengecard
+            cardHeight={384}
+            cardWidth={285}
+            index={1}
+            indexSlider={3}
+            key="1"
+            moveToSlide={[Function]}
+            userChallenge={
+              Object {
+                "action": Object {
+                  "ecogesture": null,
+                  "startDate": null,
+                  "state": 0,
                 },
-                "id": "QUIZ001",
-                "questions": Array [
-                  Object {
-                    "answers": Array [
-                      Object {
-                        "answerLabel": "86 km",
-                        "isTrue": true,
-                      },
-                      Object {
-                        "answerLabel": "78 km",
-                        "isTrue": false,
-                      },
-                      Object {
-                        "answerLabel": "56 km",
-                        "isTrue": false,
-                      },
-                    ],
-                    "explanation": "L’aqueduc du Gier est un des aqueducs antiques de Lyon desservant la ville antique de Lugdunum. Avec ses 86 km il est le plus long des quatre aqueducs ayant alimenté la ville en eau, et celui dont les structures sont le mieux conservées. Il doit son nom au fait qu'il puise aux sources du Gier, affluent du Rhône",
-                    "questionLabel": "Quelle longueur faisait l’aqueduc du Gier pour acheminer l’eau sur Lyon à l’époque romaine ?",
-                    "result": 0,
-                    "source": "string",
-                  },
-                  Object {
-                    "answers": Array [
-                      Object {
-                        "answerLabel": "1 point d’eau public pour 800 habitants.",
-                        "isTrue": true,
-                      },
-                      Object {
-                        "answerLabel": "1 point d’eau public pour 400 habitants.",
-                        "isTrue": false,
-                      },
-                      Object {
-                        "answerLabel": "1 point d’eau public pour 200 habitants.",
-                        "isTrue": false,
-                      },
-                    ],
-                    "explanation": "string",
-                    "questionLabel": "En 1800 à Lyon, combien de points d'eau y avait-il par habitants ?",
-                    "result": 0,
-                    "source": "string",
-                  },
-                  Object {
-                    "answers": Array [
-                      Object {
-                        "answerLabel": "François Mitterrand",
-                        "isTrue": false,
-                      },
-                      Object {
-                        "answerLabel": "Napoléon Ier",
-                        "isTrue": true,
-                      },
-                      Object {
-                        "answerLabel": "Napoléon III",
-                        "isTrue": false,
-                      },
-                    ],
-                    "explanation": "string",
-                    "questionLabel": "Qui officialise la création de la Compagnie Générale des eaux ?",
-                    "result": 0,
-                    "source": "string",
-                  },
-                  Object {
-                    "answers": Array [
-                      Object {
-                        "answerLabel": "string",
-                        "isTrue": false,
-                      },
-                      Object {
-                        "answerLabel": "string",
-                        "isTrue": false,
-                      },
-                      Object {
-                        "answerLabel": "Aristide Dumont",
-                        "isTrue": true,
-                      },
-                    ],
-                    "explanation": "string",
-                    "questionLabel": "Quel ingénieur est à l’origine du projet d’alimentation en eau en 1856 ?",
+                "description": "Description challenge 2",
+                "duel": Object {
+                  "description": "Je parie un ours polaire que vous ne pouvez pas consommer moins que #CONSUMPTION € en 1 semaine",
+                  "duration": "P30D",
+                  "fluidTypes": Array [],
+                  "id": "DUEL001",
+                  "startDate": null,
+                  "state": 0,
+                  "threshold": 0,
+                  "title": "Title DUEL001",
+                  "userConsumption": 0,
+                },
+                "endingDate": null,
+                "exploration": Object {
+                  "complementary_description": "Refaire un tour dans son profil si déjà fait",
+                  "date": null,
+                  "description": "Avoir complété son profil",
+                  "ecogesture_id": "",
+                  "fluid_condition": Array [],
+                  "id": "EXPLORATION001",
+                  "message_success": "Vous avez complété votre profil ou refait un tour dans votre profil",
+                  "progress": 0,
+                  "state": 0,
+                  "target": 1,
+                  "type": 1,
+                },
+                "id": "CHALLENGE0002",
+                "progress": Object {
+                  "actionProgress": 0,
+                  "explorationProgress": 0,
+                  "quizProgress": 0,
+                },
+                "quiz": Object {
+                  "customQuestion": Object {
+                    "interval": 20,
+                    "period": Object {},
+                    "questionLabel": "Custom1",
                     "result": 0,
-                    "source": "string",
+                    "singleFluid": false,
+                    "timeStep": 20,
+                    "type": 0,
                   },
-                ],
-                "result": 0,
+                  "id": "QUIZ001",
+                  "questions": Array [
+                    Object {
+                      "answers": Array [
+                        Object {
+                          "answerLabel": "86 km",
+                          "isTrue": true,
+                        },
+                        Object {
+                          "answerLabel": "78 km",
+                          "isTrue": false,
+                        },
+                        Object {
+                          "answerLabel": "56 km",
+                          "isTrue": false,
+                        },
+                      ],
+                      "explanation": "L’aqueduc du Gier est un des aqueducs antiques de Lyon desservant la ville antique de Lugdunum. Avec ses 86 km il est le plus long des quatre aqueducs ayant alimenté la ville en eau, et celui dont les structures sont le mieux conservées. Il doit son nom au fait qu'il puise aux sources du Gier, affluent du Rhône",
+                      "questionLabel": "Quelle longueur faisait l’aqueduc du Gier pour acheminer l’eau sur Lyon à l’époque romaine ?",
+                      "result": 0,
+                      "source": "string",
+                    },
+                    Object {
+                      "answers": Array [
+                        Object {
+                          "answerLabel": "1 point d’eau public pour 800 habitants.",
+                          "isTrue": true,
+                        },
+                        Object {
+                          "answerLabel": "1 point d’eau public pour 400 habitants.",
+                          "isTrue": false,
+                        },
+                        Object {
+                          "answerLabel": "1 point d’eau public pour 200 habitants.",
+                          "isTrue": false,
+                        },
+                      ],
+                      "explanation": "string",
+                      "questionLabel": "En 1800 à Lyon, combien de points d'eau y avait-il par habitants ?",
+                      "result": 0,
+                      "source": "string",
+                    },
+                    Object {
+                      "answers": Array [
+                        Object {
+                          "answerLabel": "François Mitterrand",
+                          "isTrue": false,
+                        },
+                        Object {
+                          "answerLabel": "Napoléon Ier",
+                          "isTrue": true,
+                        },
+                        Object {
+                          "answerLabel": "Napoléon III",
+                          "isTrue": false,
+                        },
+                      ],
+                      "explanation": "string",
+                      "questionLabel": "Qui officialise la création de la Compagnie Générale des eaux ?",
+                      "result": 0,
+                      "source": "string",
+                    },
+                    Object {
+                      "answers": Array [
+                        Object {
+                          "answerLabel": "string",
+                          "isTrue": false,
+                        },
+                        Object {
+                          "answerLabel": "string",
+                          "isTrue": false,
+                        },
+                        Object {
+                          "answerLabel": "Aristide Dumont",
+                          "isTrue": true,
+                        },
+                      ],
+                      "explanation": "string",
+                      "questionLabel": "Quel ingénieur est à l’origine du projet d’alimentation en eau en 1856 ?",
+                      "result": 0,
+                      "source": "string",
+                    },
+                  ],
+                  "result": 0,
+                  "startDate": null,
+                  "state": 0,
+                },
                 "startDate": null,
-                "state": 0,
-              },
-              "startDate": null,
-              "state": 4,
-              "success": 1,
-              "target": 15,
-              "title": "Challenge 2",
+                "state": 4,
+                "success": 1,
+                "target": 15,
+                "title": "Challenge 2",
+              }
             }
-          }
-        />
-        <ChallengeCard
-          cardHeight={384}
-          cardWidth={285}
-          index={2}
-          indexSlider={0}
-          moveToSlide={[Function]}
-          userChallenge={
-            Object {
-              "action": Object {
-                "ecogesture": null,
-                "startDate": null,
-                "state": 0,
-              },
-              "description": "Description challenge 3",
-              "duel": Object {
-                "description": "Je parie un ours polaire que vous ne pouvez pas consommer moins que #CONSUMPTION € en 1 semaine",
-                "duration": "P30D",
-                "fluidTypes": Array [],
-                "id": "DUEL001",
-                "startDate": null,
-                "state": 0,
-                "threshold": 0,
-                "title": "Title DUEL001",
-                "userConsumption": 0,
-              },
-              "endingDate": null,
-              "exploration": Object {
-                "complementary_description": "Refaire un tour dans son profil si déjà fait",
-                "date": null,
-                "description": "Avoir complété son profil",
-                "ecogesture_id": "",
-                "fluid_condition": Array [],
-                "id": "EXPLORATION001",
-                "message_success": "Vous avez complété votre profil ou refait un tour dans votre profil",
-                "progress": 0,
-                "state": 0,
-                "target": 1,
-                "type": 1,
-              },
-              "id": "CHALLENGE0003",
-              "progress": Object {
-                "actionProgress": 0,
-                "explorationProgress": 0,
-                "quizProgress": 0,
-              },
-              "quiz": Object {
-                "customQuestion": Object {
-                  "interval": 20,
-                  "period": Object {},
-                  "questionLabel": "Custom1",
-                  "result": 0,
-                  "singleFluid": false,
-                  "timeStep": 20,
-                  "type": 0,
+          />
+          <mock-challengecard
+            cardHeight={384}
+            cardWidth={285}
+            index={2}
+            indexSlider={3}
+            key="2"
+            moveToSlide={[Function]}
+            userChallenge={
+              Object {
+                "action": Object {
+                  "ecogesture": null,
+                  "startDate": null,
+                  "state": 0,
                 },
-                "id": "QUIZ001",
-                "questions": Array [
-                  Object {
-                    "answers": Array [
-                      Object {
-                        "answerLabel": "86 km",
-                        "isTrue": true,
-                      },
-                      Object {
-                        "answerLabel": "78 km",
-                        "isTrue": false,
-                      },
-                      Object {
-                        "answerLabel": "56 km",
-                        "isTrue": false,
-                      },
-                    ],
-                    "explanation": "L’aqueduc du Gier est un des aqueducs antiques de Lyon desservant la ville antique de Lugdunum. Avec ses 86 km il est le plus long des quatre aqueducs ayant alimenté la ville en eau, et celui dont les structures sont le mieux conservées. Il doit son nom au fait qu'il puise aux sources du Gier, affluent du Rhône",
-                    "questionLabel": "Quelle longueur faisait l’aqueduc du Gier pour acheminer l’eau sur Lyon à l’époque romaine ?",
-                    "result": 0,
-                    "source": "string",
-                  },
-                  Object {
-                    "answers": Array [
-                      Object {
-                        "answerLabel": "1 point d’eau public pour 800 habitants.",
-                        "isTrue": true,
-                      },
-                      Object {
-                        "answerLabel": "1 point d’eau public pour 400 habitants.",
-                        "isTrue": false,
-                      },
-                      Object {
-                        "answerLabel": "1 point d’eau public pour 200 habitants.",
-                        "isTrue": false,
-                      },
-                    ],
-                    "explanation": "string",
-                    "questionLabel": "En 1800 à Lyon, combien de points d'eau y avait-il par habitants ?",
-                    "result": 0,
-                    "source": "string",
-                  },
-                  Object {
-                    "answers": Array [
-                      Object {
-                        "answerLabel": "François Mitterrand",
-                        "isTrue": false,
-                      },
-                      Object {
-                        "answerLabel": "Napoléon Ier",
-                        "isTrue": true,
-                      },
-                      Object {
-                        "answerLabel": "Napoléon III",
-                        "isTrue": false,
-                      },
-                    ],
-                    "explanation": "string",
-                    "questionLabel": "Qui officialise la création de la Compagnie Générale des eaux ?",
-                    "result": 0,
-                    "source": "string",
-                  },
-                  Object {
-                    "answers": Array [
-                      Object {
-                        "answerLabel": "string",
-                        "isTrue": false,
-                      },
-                      Object {
-                        "answerLabel": "string",
-                        "isTrue": false,
-                      },
-                      Object {
-                        "answerLabel": "Aristide Dumont",
-                        "isTrue": true,
-                      },
-                    ],
-                    "explanation": "string",
-                    "questionLabel": "Quel ingénieur est à l’origine du projet d’alimentation en eau en 1856 ?",
+                "description": "Description challenge 3",
+                "duel": Object {
+                  "description": "Je parie un ours polaire que vous ne pouvez pas consommer moins que #CONSUMPTION € en 1 semaine",
+                  "duration": "P30D",
+                  "fluidTypes": Array [],
+                  "id": "DUEL001",
+                  "startDate": null,
+                  "state": 0,
+                  "threshold": 0,
+                  "title": "Title DUEL001",
+                  "userConsumption": 0,
+                },
+                "endingDate": null,
+                "exploration": Object {
+                  "complementary_description": "Refaire un tour dans son profil si déjà fait",
+                  "date": null,
+                  "description": "Avoir complété son profil",
+                  "ecogesture_id": "",
+                  "fluid_condition": Array [],
+                  "id": "EXPLORATION001",
+                  "message_success": "Vous avez complété votre profil ou refait un tour dans votre profil",
+                  "progress": 0,
+                  "state": 0,
+                  "target": 1,
+                  "type": 1,
+                },
+                "id": "CHALLENGE0003",
+                "progress": Object {
+                  "actionProgress": 0,
+                  "explorationProgress": 0,
+                  "quizProgress": 0,
+                },
+                "quiz": Object {
+                  "customQuestion": Object {
+                    "interval": 20,
+                    "period": Object {},
+                    "questionLabel": "Custom1",
                     "result": 0,
-                    "source": "string",
+                    "singleFluid": false,
+                    "timeStep": 20,
+                    "type": 0,
                   },
-                ],
-                "result": 0,
+                  "id": "QUIZ001",
+                  "questions": Array [
+                    Object {
+                      "answers": Array [
+                        Object {
+                          "answerLabel": "86 km",
+                          "isTrue": true,
+                        },
+                        Object {
+                          "answerLabel": "78 km",
+                          "isTrue": false,
+                        },
+                        Object {
+                          "answerLabel": "56 km",
+                          "isTrue": false,
+                        },
+                      ],
+                      "explanation": "L’aqueduc du Gier est un des aqueducs antiques de Lyon desservant la ville antique de Lugdunum. Avec ses 86 km il est le plus long des quatre aqueducs ayant alimenté la ville en eau, et celui dont les structures sont le mieux conservées. Il doit son nom au fait qu'il puise aux sources du Gier, affluent du Rhône",
+                      "questionLabel": "Quelle longueur faisait l’aqueduc du Gier pour acheminer l’eau sur Lyon à l’époque romaine ?",
+                      "result": 0,
+                      "source": "string",
+                    },
+                    Object {
+                      "answers": Array [
+                        Object {
+                          "answerLabel": "1 point d’eau public pour 800 habitants.",
+                          "isTrue": true,
+                        },
+                        Object {
+                          "answerLabel": "1 point d’eau public pour 400 habitants.",
+                          "isTrue": false,
+                        },
+                        Object {
+                          "answerLabel": "1 point d’eau public pour 200 habitants.",
+                          "isTrue": false,
+                        },
+                      ],
+                      "explanation": "string",
+                      "questionLabel": "En 1800 à Lyon, combien de points d'eau y avait-il par habitants ?",
+                      "result": 0,
+                      "source": "string",
+                    },
+                    Object {
+                      "answers": Array [
+                        Object {
+                          "answerLabel": "François Mitterrand",
+                          "isTrue": false,
+                        },
+                        Object {
+                          "answerLabel": "Napoléon Ier",
+                          "isTrue": true,
+                        },
+                        Object {
+                          "answerLabel": "Napoléon III",
+                          "isTrue": false,
+                        },
+                      ],
+                      "explanation": "string",
+                      "questionLabel": "Qui officialise la création de la Compagnie Générale des eaux ?",
+                      "result": 0,
+                      "source": "string",
+                    },
+                    Object {
+                      "answers": Array [
+                        Object {
+                          "answerLabel": "string",
+                          "isTrue": false,
+                        },
+                        Object {
+                          "answerLabel": "string",
+                          "isTrue": false,
+                        },
+                        Object {
+                          "answerLabel": "Aristide Dumont",
+                          "isTrue": true,
+                        },
+                      ],
+                      "explanation": "string",
+                      "questionLabel": "Quel ingénieur est à l’origine du projet d’alimentation en eau en 1856 ?",
+                      "result": 0,
+                      "source": "string",
+                    },
+                  ],
+                  "result": 0,
+                  "startDate": null,
+                  "state": 0,
+                },
                 "startDate": null,
-                "state": 0,
-              },
-              "startDate": null,
-              "state": 2,
-              "success": 0,
-              "target": 15,
-              "title": "Challenge 3",
+                "state": 2,
+                "success": 0,
+                "target": 15,
+                "title": "Challenge 3",
+              }
             }
-          }
-        />
-        <ChallengeCard
-          cardHeight={384}
-          cardWidth={285}
-          index={3}
-          indexSlider={0}
-          moveToSlide={[Function]}
-          userChallenge={
-            Object {
-              "action": Object {
-                "ecogesture": null,
-                "startDate": null,
-                "state": 0,
-              },
-              "description": "Description challenge 4",
-              "duel": Object {
-                "description": "Je parie un ours polaire que vous ne pouvez pas consommer moins que #CONSUMPTION € en 1 semaine",
-                "duration": "P30D",
-                "fluidTypes": Array [],
-                "id": "DUEL001",
-                "startDate": null,
-                "state": 0,
-                "threshold": 0,
-                "title": "Title DUEL001",
-                "userConsumption": 0,
-              },
-              "endingDate": null,
-              "exploration": Object {
-                "complementary_description": "Refaire un tour dans son profil si déjà fait",
-                "date": null,
-                "description": "Avoir complété son profil",
-                "ecogesture_id": "",
-                "fluid_condition": Array [],
-                "id": "EXPLORATION001",
-                "message_success": "Vous avez complété votre profil ou refait un tour dans votre profil",
-                "progress": 0,
-                "state": 0,
-                "target": 1,
-                "type": 1,
-              },
-              "id": "CHALLENGE0004",
-              "progress": Object {
-                "actionProgress": 0,
-                "explorationProgress": 0,
-                "quizProgress": 0,
-              },
-              "quiz": Object {
-                "customQuestion": Object {
-                  "interval": 20,
-                  "period": Object {},
-                  "questionLabel": "Custom1",
-                  "result": 0,
-                  "singleFluid": false,
-                  "timeStep": 20,
-                  "type": 0,
+          />
+          <mock-challengecard
+            cardHeight={384}
+            cardWidth={285}
+            index={3}
+            indexSlider={3}
+            key="3"
+            moveToSlide={[Function]}
+            userChallenge={
+              Object {
+                "action": Object {
+                  "ecogesture": null,
+                  "startDate": null,
+                  "state": 0,
                 },
-                "id": "QUIZ001",
-                "questions": Array [
-                  Object {
-                    "answers": Array [
-                      Object {
-                        "answerLabel": "86 km",
-                        "isTrue": true,
-                      },
-                      Object {
-                        "answerLabel": "78 km",
-                        "isTrue": false,
-                      },
-                      Object {
-                        "answerLabel": "56 km",
-                        "isTrue": false,
-                      },
-                    ],
-                    "explanation": "L’aqueduc du Gier est un des aqueducs antiques de Lyon desservant la ville antique de Lugdunum. Avec ses 86 km il est le plus long des quatre aqueducs ayant alimenté la ville en eau, et celui dont les structures sont le mieux conservées. Il doit son nom au fait qu'il puise aux sources du Gier, affluent du Rhône",
-                    "questionLabel": "Quelle longueur faisait l’aqueduc du Gier pour acheminer l’eau sur Lyon à l’époque romaine ?",
-                    "result": 0,
-                    "source": "string",
-                  },
-                  Object {
-                    "answers": Array [
-                      Object {
-                        "answerLabel": "1 point d’eau public pour 800 habitants.",
-                        "isTrue": true,
-                      },
-                      Object {
-                        "answerLabel": "1 point d’eau public pour 400 habitants.",
-                        "isTrue": false,
-                      },
-                      Object {
-                        "answerLabel": "1 point d’eau public pour 200 habitants.",
-                        "isTrue": false,
-                      },
-                    ],
-                    "explanation": "string",
-                    "questionLabel": "En 1800 à Lyon, combien de points d'eau y avait-il par habitants ?",
-                    "result": 0,
-                    "source": "string",
-                  },
-                  Object {
-                    "answers": Array [
-                      Object {
-                        "answerLabel": "François Mitterrand",
-                        "isTrue": false,
-                      },
-                      Object {
-                        "answerLabel": "Napoléon Ier",
-                        "isTrue": true,
-                      },
-                      Object {
-                        "answerLabel": "Napoléon III",
-                        "isTrue": false,
-                      },
-                    ],
-                    "explanation": "string",
-                    "questionLabel": "Qui officialise la création de la Compagnie Générale des eaux ?",
-                    "result": 0,
-                    "source": "string",
-                  },
-                  Object {
-                    "answers": Array [
-                      Object {
-                        "answerLabel": "string",
-                        "isTrue": false,
-                      },
-                      Object {
-                        "answerLabel": "string",
-                        "isTrue": false,
-                      },
-                      Object {
-                        "answerLabel": "Aristide Dumont",
-                        "isTrue": true,
-                      },
-                    ],
-                    "explanation": "string",
-                    "questionLabel": "Quel ingénieur est à l’origine du projet d’alimentation en eau en 1856 ?",
+                "description": "Description challenge 4",
+                "duel": Object {
+                  "description": "Je parie un ours polaire que vous ne pouvez pas consommer moins que #CONSUMPTION € en 1 semaine",
+                  "duration": "P30D",
+                  "fluidTypes": Array [],
+                  "id": "DUEL001",
+                  "startDate": null,
+                  "state": 0,
+                  "threshold": 0,
+                  "title": "Title DUEL001",
+                  "userConsumption": 0,
+                },
+                "endingDate": null,
+                "exploration": Object {
+                  "complementary_description": "Refaire un tour dans son profil si déjà fait",
+                  "date": null,
+                  "description": "Avoir complété son profil",
+                  "ecogesture_id": "",
+                  "fluid_condition": Array [],
+                  "id": "EXPLORATION001",
+                  "message_success": "Vous avez complété votre profil ou refait un tour dans votre profil",
+                  "progress": 0,
+                  "state": 0,
+                  "target": 1,
+                  "type": 1,
+                },
+                "id": "CHALLENGE0004",
+                "progress": Object {
+                  "actionProgress": 0,
+                  "explorationProgress": 0,
+                  "quizProgress": 0,
+                },
+                "quiz": Object {
+                  "customQuestion": Object {
+                    "interval": 20,
+                    "period": Object {},
+                    "questionLabel": "Custom1",
                     "result": 0,
-                    "source": "string",
+                    "singleFluid": false,
+                    "timeStep": 20,
+                    "type": 0,
                   },
-                ],
-                "result": 0,
+                  "id": "QUIZ001",
+                  "questions": Array [
+                    Object {
+                      "answers": Array [
+                        Object {
+                          "answerLabel": "86 km",
+                          "isTrue": true,
+                        },
+                        Object {
+                          "answerLabel": "78 km",
+                          "isTrue": false,
+                        },
+                        Object {
+                          "answerLabel": "56 km",
+                          "isTrue": false,
+                        },
+                      ],
+                      "explanation": "L’aqueduc du Gier est un des aqueducs antiques de Lyon desservant la ville antique de Lugdunum. Avec ses 86 km il est le plus long des quatre aqueducs ayant alimenté la ville en eau, et celui dont les structures sont le mieux conservées. Il doit son nom au fait qu'il puise aux sources du Gier, affluent du Rhône",
+                      "questionLabel": "Quelle longueur faisait l’aqueduc du Gier pour acheminer l’eau sur Lyon à l’époque romaine ?",
+                      "result": 0,
+                      "source": "string",
+                    },
+                    Object {
+                      "answers": Array [
+                        Object {
+                          "answerLabel": "1 point d’eau public pour 800 habitants.",
+                          "isTrue": true,
+                        },
+                        Object {
+                          "answerLabel": "1 point d’eau public pour 400 habitants.",
+                          "isTrue": false,
+                        },
+                        Object {
+                          "answerLabel": "1 point d’eau public pour 200 habitants.",
+                          "isTrue": false,
+                        },
+                      ],
+                      "explanation": "string",
+                      "questionLabel": "En 1800 à Lyon, combien de points d'eau y avait-il par habitants ?",
+                      "result": 0,
+                      "source": "string",
+                    },
+                    Object {
+                      "answers": Array [
+                        Object {
+                          "answerLabel": "François Mitterrand",
+                          "isTrue": false,
+                        },
+                        Object {
+                          "answerLabel": "Napoléon Ier",
+                          "isTrue": true,
+                        },
+                        Object {
+                          "answerLabel": "Napoléon III",
+                          "isTrue": false,
+                        },
+                      ],
+                      "explanation": "string",
+                      "questionLabel": "Qui officialise la création de la Compagnie Générale des eaux ?",
+                      "result": 0,
+                      "source": "string",
+                    },
+                    Object {
+                      "answers": Array [
+                        Object {
+                          "answerLabel": "string",
+                          "isTrue": false,
+                        },
+                        Object {
+                          "answerLabel": "string",
+                          "isTrue": false,
+                        },
+                        Object {
+                          "answerLabel": "Aristide Dumont",
+                          "isTrue": true,
+                        },
+                      ],
+                      "explanation": "string",
+                      "questionLabel": "Quel ingénieur est à l’origine du projet d’alimentation en eau en 1856 ?",
+                      "result": 0,
+                      "source": "string",
+                    },
+                  ],
+                  "result": 0,
+                  "startDate": null,
+                  "state": 0,
+                },
                 "startDate": null,
-                "state": 0,
-              },
-              "startDate": null,
-              "state": 1,
-              "success": 0,
-              "target": 15,
-              "title": "Challenge 4",
+                "state": 1,
+                "success": 0,
+                "target": 15,
+                "title": "Challenge 4",
+              }
             }
-          }
-        />
-        <ChallengeCard
-          cardHeight={384}
-          cardWidth={285}
-          index={4}
-          indexSlider={0}
-          moveToSlide={[Function]}
-          userChallenge={
-            Object {
-              "action": Object {
-                "ecogesture": null,
-                "startDate": null,
-                "state": 0,
-              },
-              "description": "Description challenge 5",
-              "duel": Object {
-                "description": "Je parie un ours polaire que vous ne pouvez pas consommer moins que #CONSUMPTION € en 1 semaine",
-                "duration": "P30D",
-                "fluidTypes": Array [],
-                "id": "DUEL001",
-                "startDate": null,
-                "state": 0,
-                "threshold": 0,
-                "title": "Title DUEL001",
-                "userConsumption": 0,
-              },
-              "endingDate": null,
-              "exploration": Object {
-                "complementary_description": "Refaire un tour dans son profil si déjà fait",
-                "date": null,
-                "description": "Avoir complété son profil",
-                "ecogesture_id": "",
-                "fluid_condition": Array [],
-                "id": "EXPLORATION001",
-                "message_success": "Vous avez complété votre profil ou refait un tour dans votre profil",
-                "progress": 0,
-                "state": 0,
-                "target": 1,
-                "type": 1,
-              },
-              "id": "CHALLENGE0005",
-              "progress": Object {
-                "actionProgress": 0,
-                "explorationProgress": 0,
-                "quizProgress": 0,
-              },
-              "quiz": Object {
-                "customQuestion": Object {
-                  "interval": 20,
-                  "period": Object {},
-                  "questionLabel": "Custom1",
-                  "result": 0,
-                  "singleFluid": false,
-                  "timeStep": 20,
-                  "type": 0,
+          />
+          <mock-challengecard
+            cardHeight={384}
+            cardWidth={285}
+            index={4}
+            indexSlider={3}
+            key="4"
+            moveToSlide={[Function]}
+            userChallenge={
+              Object {
+                "action": Object {
+                  "ecogesture": null,
+                  "startDate": null,
+                  "state": 0,
                 },
-                "id": "QUIZ001",
-                "questions": Array [
-                  Object {
-                    "answers": Array [
-                      Object {
-                        "answerLabel": "86 km",
-                        "isTrue": true,
-                      },
-                      Object {
-                        "answerLabel": "78 km",
-                        "isTrue": false,
-                      },
-                      Object {
-                        "answerLabel": "56 km",
-                        "isTrue": false,
-                      },
-                    ],
-                    "explanation": "L’aqueduc du Gier est un des aqueducs antiques de Lyon desservant la ville antique de Lugdunum. Avec ses 86 km il est le plus long des quatre aqueducs ayant alimenté la ville en eau, et celui dont les structures sont le mieux conservées. Il doit son nom au fait qu'il puise aux sources du Gier, affluent du Rhône",
-                    "questionLabel": "Quelle longueur faisait l’aqueduc du Gier pour acheminer l’eau sur Lyon à l’époque romaine ?",
-                    "result": 0,
-                    "source": "string",
-                  },
-                  Object {
-                    "answers": Array [
-                      Object {
-                        "answerLabel": "1 point d’eau public pour 800 habitants.",
-                        "isTrue": true,
-                      },
-                      Object {
-                        "answerLabel": "1 point d’eau public pour 400 habitants.",
-                        "isTrue": false,
-                      },
-                      Object {
-                        "answerLabel": "1 point d’eau public pour 200 habitants.",
-                        "isTrue": false,
-                      },
-                    ],
-                    "explanation": "string",
-                    "questionLabel": "En 1800 à Lyon, combien de points d'eau y avait-il par habitants ?",
-                    "result": 0,
-                    "source": "string",
-                  },
-                  Object {
-                    "answers": Array [
-                      Object {
-                        "answerLabel": "François Mitterrand",
-                        "isTrue": false,
-                      },
-                      Object {
-                        "answerLabel": "Napoléon Ier",
-                        "isTrue": true,
-                      },
-                      Object {
-                        "answerLabel": "Napoléon III",
-                        "isTrue": false,
-                      },
-                    ],
-                    "explanation": "string",
-                    "questionLabel": "Qui officialise la création de la Compagnie Générale des eaux ?",
-                    "result": 0,
-                    "source": "string",
-                  },
-                  Object {
-                    "answers": Array [
-                      Object {
-                        "answerLabel": "string",
-                        "isTrue": false,
-                      },
-                      Object {
-                        "answerLabel": "string",
-                        "isTrue": false,
-                      },
-                      Object {
-                        "answerLabel": "Aristide Dumont",
-                        "isTrue": true,
-                      },
-                    ],
-                    "explanation": "string",
-                    "questionLabel": "Quel ingénieur est à l’origine du projet d’alimentation en eau en 1856 ?",
+                "description": "Description challenge 5",
+                "duel": Object {
+                  "description": "Je parie un ours polaire que vous ne pouvez pas consommer moins que #CONSUMPTION € en 1 semaine",
+                  "duration": "P30D",
+                  "fluidTypes": Array [],
+                  "id": "DUEL001",
+                  "startDate": null,
+                  "state": 0,
+                  "threshold": 0,
+                  "title": "Title DUEL001",
+                  "userConsumption": 0,
+                },
+                "endingDate": null,
+                "exploration": Object {
+                  "complementary_description": "Refaire un tour dans son profil si déjà fait",
+                  "date": null,
+                  "description": "Avoir complété son profil",
+                  "ecogesture_id": "",
+                  "fluid_condition": Array [],
+                  "id": "EXPLORATION001",
+                  "message_success": "Vous avez complété votre profil ou refait un tour dans votre profil",
+                  "progress": 0,
+                  "state": 0,
+                  "target": 1,
+                  "type": 1,
+                },
+                "id": "CHALLENGE0005",
+                "progress": Object {
+                  "actionProgress": 0,
+                  "explorationProgress": 0,
+                  "quizProgress": 0,
+                },
+                "quiz": Object {
+                  "customQuestion": Object {
+                    "interval": 20,
+                    "period": Object {},
+                    "questionLabel": "Custom1",
                     "result": 0,
-                    "source": "string",
+                    "singleFluid": false,
+                    "timeStep": 20,
+                    "type": 0,
                   },
-                ],
-                "result": 0,
+                  "id": "QUIZ001",
+                  "questions": Array [
+                    Object {
+                      "answers": Array [
+                        Object {
+                          "answerLabel": "86 km",
+                          "isTrue": true,
+                        },
+                        Object {
+                          "answerLabel": "78 km",
+                          "isTrue": false,
+                        },
+                        Object {
+                          "answerLabel": "56 km",
+                          "isTrue": false,
+                        },
+                      ],
+                      "explanation": "L’aqueduc du Gier est un des aqueducs antiques de Lyon desservant la ville antique de Lugdunum. Avec ses 86 km il est le plus long des quatre aqueducs ayant alimenté la ville en eau, et celui dont les structures sont le mieux conservées. Il doit son nom au fait qu'il puise aux sources du Gier, affluent du Rhône",
+                      "questionLabel": "Quelle longueur faisait l’aqueduc du Gier pour acheminer l’eau sur Lyon à l’époque romaine ?",
+                      "result": 0,
+                      "source": "string",
+                    },
+                    Object {
+                      "answers": Array [
+                        Object {
+                          "answerLabel": "1 point d’eau public pour 800 habitants.",
+                          "isTrue": true,
+                        },
+                        Object {
+                          "answerLabel": "1 point d’eau public pour 400 habitants.",
+                          "isTrue": false,
+                        },
+                        Object {
+                          "answerLabel": "1 point d’eau public pour 200 habitants.",
+                          "isTrue": false,
+                        },
+                      ],
+                      "explanation": "string",
+                      "questionLabel": "En 1800 à Lyon, combien de points d'eau y avait-il par habitants ?",
+                      "result": 0,
+                      "source": "string",
+                    },
+                    Object {
+                      "answers": Array [
+                        Object {
+                          "answerLabel": "François Mitterrand",
+                          "isTrue": false,
+                        },
+                        Object {
+                          "answerLabel": "Napoléon Ier",
+                          "isTrue": true,
+                        },
+                        Object {
+                          "answerLabel": "Napoléon III",
+                          "isTrue": false,
+                        },
+                      ],
+                      "explanation": "string",
+                      "questionLabel": "Qui officialise la création de la Compagnie Générale des eaux ?",
+                      "result": 0,
+                      "source": "string",
+                    },
+                    Object {
+                      "answers": Array [
+                        Object {
+                          "answerLabel": "string",
+                          "isTrue": false,
+                        },
+                        Object {
+                          "answerLabel": "string",
+                          "isTrue": false,
+                        },
+                        Object {
+                          "answerLabel": "Aristide Dumont",
+                          "isTrue": true,
+                        },
+                      ],
+                      "explanation": "string",
+                      "questionLabel": "Quel ingénieur est à l’origine du projet d’alimentation en eau en 1856 ?",
+                      "result": 0,
+                      "source": "string",
+                    },
+                  ],
+                  "result": 0,
+                  "startDate": null,
+                  "state": 0,
+                },
                 "startDate": null,
                 "state": 0,
-              },
-              "startDate": null,
-              "state": 0,
-              "success": 0,
-              "target": 15,
-              "title": "Challenge 5",
+                "success": 0,
+                "target": 15,
+                "title": "Challenge 5",
+              }
             }
-          }
-        />
-        <ChallengeCard
-          cardHeight={384}
-          cardWidth={285}
-          index={5}
-          indexSlider={0}
-          moveToSlide={[Function]}
-          userChallenge={
-            Object {
-              "action": Object {
-                "ecogesture": null,
-                "startDate": null,
-                "state": 0,
-              },
-              "description": "Description challenge 6",
-              "duel": Object {
-                "description": "Je parie un ours polaire que vous ne pouvez pas consommer moins que #CONSUMPTION € en 1 semaine",
-                "duration": "P30D",
-                "fluidTypes": Array [],
-                "id": "DUEL001",
-                "startDate": null,
-                "state": 0,
-                "threshold": 0,
-                "title": "Title DUEL001",
-                "userConsumption": 0,
-              },
-              "endingDate": null,
-              "exploration": Object {
-                "complementary_description": "Refaire un tour dans son profil si déjà fait",
-                "date": null,
-                "description": "Avoir complété son profil",
-                "ecogesture_id": "",
-                "fluid_condition": Array [],
-                "id": "EXPLORATION001",
-                "message_success": "Vous avez complété votre profil ou refait un tour dans votre profil",
-                "progress": 0,
-                "state": 0,
-                "target": 1,
-                "type": 1,
-              },
-              "id": "CHALLENGE0006",
-              "progress": Object {
-                "actionProgress": 0,
-                "explorationProgress": 0,
-                "quizProgress": 0,
-              },
-              "quiz": Object {
-                "customQuestion": Object {
-                  "interval": 20,
-                  "period": Object {},
-                  "questionLabel": "Custom1",
-                  "result": 0,
-                  "singleFluid": false,
-                  "timeStep": 20,
-                  "type": 0,
+          />
+          <mock-challengecard
+            cardHeight={384}
+            cardWidth={285}
+            index={5}
+            indexSlider={3}
+            key="5"
+            moveToSlide={[Function]}
+            userChallenge={
+              Object {
+                "action": Object {
+                  "ecogesture": null,
+                  "startDate": null,
+                  "state": 0,
                 },
-                "id": "QUIZ001",
-                "questions": Array [
-                  Object {
-                    "answers": Array [
-                      Object {
-                        "answerLabel": "86 km",
-                        "isTrue": true,
-                      },
-                      Object {
-                        "answerLabel": "78 km",
-                        "isTrue": false,
-                      },
-                      Object {
-                        "answerLabel": "56 km",
-                        "isTrue": false,
-                      },
-                    ],
-                    "explanation": "L’aqueduc du Gier est un des aqueducs antiques de Lyon desservant la ville antique de Lugdunum. Avec ses 86 km il est le plus long des quatre aqueducs ayant alimenté la ville en eau, et celui dont les structures sont le mieux conservées. Il doit son nom au fait qu'il puise aux sources du Gier, affluent du Rhône",
-                    "questionLabel": "Quelle longueur faisait l’aqueduc du Gier pour acheminer l’eau sur Lyon à l’époque romaine ?",
-                    "result": 0,
-                    "source": "string",
-                  },
-                  Object {
-                    "answers": Array [
-                      Object {
-                        "answerLabel": "1 point d’eau public pour 800 habitants.",
-                        "isTrue": true,
-                      },
-                      Object {
-                        "answerLabel": "1 point d’eau public pour 400 habitants.",
-                        "isTrue": false,
-                      },
-                      Object {
-                        "answerLabel": "1 point d’eau public pour 200 habitants.",
-                        "isTrue": false,
-                      },
-                    ],
-                    "explanation": "string",
-                    "questionLabel": "En 1800 à Lyon, combien de points d'eau y avait-il par habitants ?",
-                    "result": 0,
-                    "source": "string",
-                  },
-                  Object {
-                    "answers": Array [
-                      Object {
-                        "answerLabel": "François Mitterrand",
-                        "isTrue": false,
-                      },
-                      Object {
-                        "answerLabel": "Napoléon Ier",
-                        "isTrue": true,
-                      },
-                      Object {
-                        "answerLabel": "Napoléon III",
-                        "isTrue": false,
-                      },
-                    ],
-                    "explanation": "string",
-                    "questionLabel": "Qui officialise la création de la Compagnie Générale des eaux ?",
-                    "result": 0,
-                    "source": "string",
-                  },
-                  Object {
-                    "answers": Array [
-                      Object {
-                        "answerLabel": "string",
-                        "isTrue": false,
-                      },
-                      Object {
-                        "answerLabel": "string",
-                        "isTrue": false,
-                      },
-                      Object {
-                        "answerLabel": "Aristide Dumont",
-                        "isTrue": true,
-                      },
-                    ],
-                    "explanation": "string",
-                    "questionLabel": "Quel ingénieur est à l’origine du projet d’alimentation en eau en 1856 ?",
+                "description": "Description challenge 6",
+                "duel": Object {
+                  "description": "Je parie un ours polaire que vous ne pouvez pas consommer moins que #CONSUMPTION € en 1 semaine",
+                  "duration": "P30D",
+                  "fluidTypes": Array [],
+                  "id": "DUEL001",
+                  "startDate": null,
+                  "state": 0,
+                  "threshold": 0,
+                  "title": "Title DUEL001",
+                  "userConsumption": 0,
+                },
+                "endingDate": null,
+                "exploration": Object {
+                  "complementary_description": "Refaire un tour dans son profil si déjà fait",
+                  "date": null,
+                  "description": "Avoir complété son profil",
+                  "ecogesture_id": "",
+                  "fluid_condition": Array [],
+                  "id": "EXPLORATION001",
+                  "message_success": "Vous avez complété votre profil ou refait un tour dans votre profil",
+                  "progress": 0,
+                  "state": 0,
+                  "target": 1,
+                  "type": 1,
+                },
+                "id": "CHALLENGE0006",
+                "progress": Object {
+                  "actionProgress": 0,
+                  "explorationProgress": 0,
+                  "quizProgress": 0,
+                },
+                "quiz": Object {
+                  "customQuestion": Object {
+                    "interval": 20,
+                    "period": Object {},
+                    "questionLabel": "Custom1",
                     "result": 0,
-                    "source": "string",
+                    "singleFluid": false,
+                    "timeStep": 20,
+                    "type": 0,
                   },
-                ],
-                "result": 0,
+                  "id": "QUIZ001",
+                  "questions": Array [
+                    Object {
+                      "answers": Array [
+                        Object {
+                          "answerLabel": "86 km",
+                          "isTrue": true,
+                        },
+                        Object {
+                          "answerLabel": "78 km",
+                          "isTrue": false,
+                        },
+                        Object {
+                          "answerLabel": "56 km",
+                          "isTrue": false,
+                        },
+                      ],
+                      "explanation": "L’aqueduc du Gier est un des aqueducs antiques de Lyon desservant la ville antique de Lugdunum. Avec ses 86 km il est le plus long des quatre aqueducs ayant alimenté la ville en eau, et celui dont les structures sont le mieux conservées. Il doit son nom au fait qu'il puise aux sources du Gier, affluent du Rhône",
+                      "questionLabel": "Quelle longueur faisait l’aqueduc du Gier pour acheminer l’eau sur Lyon à l’époque romaine ?",
+                      "result": 0,
+                      "source": "string",
+                    },
+                    Object {
+                      "answers": Array [
+                        Object {
+                          "answerLabel": "1 point d’eau public pour 800 habitants.",
+                          "isTrue": true,
+                        },
+                        Object {
+                          "answerLabel": "1 point d’eau public pour 400 habitants.",
+                          "isTrue": false,
+                        },
+                        Object {
+                          "answerLabel": "1 point d’eau public pour 200 habitants.",
+                          "isTrue": false,
+                        },
+                      ],
+                      "explanation": "string",
+                      "questionLabel": "En 1800 à Lyon, combien de points d'eau y avait-il par habitants ?",
+                      "result": 0,
+                      "source": "string",
+                    },
+                    Object {
+                      "answers": Array [
+                        Object {
+                          "answerLabel": "François Mitterrand",
+                          "isTrue": false,
+                        },
+                        Object {
+                          "answerLabel": "Napoléon Ier",
+                          "isTrue": true,
+                        },
+                        Object {
+                          "answerLabel": "Napoléon III",
+                          "isTrue": false,
+                        },
+                      ],
+                      "explanation": "string",
+                      "questionLabel": "Qui officialise la création de la Compagnie Générale des eaux ?",
+                      "result": 0,
+                      "source": "string",
+                    },
+                    Object {
+                      "answers": Array [
+                        Object {
+                          "answerLabel": "string",
+                          "isTrue": false,
+                        },
+                        Object {
+                          "answerLabel": "string",
+                          "isTrue": false,
+                        },
+                        Object {
+                          "answerLabel": "Aristide Dumont",
+                          "isTrue": true,
+                        },
+                      ],
+                      "explanation": "string",
+                      "questionLabel": "Quel ingénieur est à l’origine du projet d’alimentation en eau en 1856 ?",
+                      "result": 0,
+                      "source": "string",
+                    },
+                  ],
+                  "result": 0,
+                  "startDate": null,
+                  "state": 0,
+                },
                 "startDate": null,
                 "state": 0,
-              },
-              "startDate": null,
-              "state": 0,
-              "success": 0,
-              "target": 15,
-              "title": "Challenge 6",
+                "success": 0,
+                "target": 15,
+                "title": "Challenge 6",
+              }
             }
-          }
-        />
+          />
+        </div>
       </div>
-    </div>
-    <div
-      className="sliderButtons"
-    >
-      <StyledIconButton
-        aria-label="challenge.accessibility.button_slider_previous"
-        icon="test-file-stub"
-        onClick={[Function]}
-        size={16}
-      />
-      <StyledIconButton
-        aria-label="challenge.accessibility.button_slider_next"
-        icon="test-file-stub"
-        onClick={[Function]}
-        size={16}
-      />
-    </div>
-  </Content>
-</React.Fragment>
+      <div
+        className="sliderButtons"
+      >
+        <StyledIconButton
+          aria-label="challenge.accessibility.button_slider_previous"
+          icon="test-file-stub"
+          onClick={[Function]}
+          size={16}
+        >
+          <WithStyles(WithStyles(ForwardRef(IconButton)))
+            aria-label="challenge.accessibility.button_slider_previous"
+            onClick={[Function]}
+          >
+            <WithStyles(ForwardRef(IconButton))
+              aria-label="challenge.accessibility.button_slider_previous"
+              classes={
+                Object {
+                  "root": "WithStyles(ForwardRef(IconButton))-root-1",
+                }
+              }
+              onClick={[Function]}
+            >
+              <ForwardRef(IconButton)
+                aria-label="challenge.accessibility.button_slider_previous"
+                classes={
+                  Object {
+                    "colorInherit": "MuiIconButton-colorInherit",
+                    "colorPrimary": "MuiIconButton-colorPrimary",
+                    "colorSecondary": "MuiIconButton-colorSecondary",
+                    "disabled": "Mui-disabled",
+                    "edgeEnd": "MuiIconButton-edgeEnd",
+                    "edgeStart": "MuiIconButton-edgeStart",
+                    "label": "MuiIconButton-label",
+                    "root": "MuiIconButton-root WithStyles(ForwardRef(IconButton))-root-1",
+                    "sizeSmall": "MuiIconButton-sizeSmall",
+                  }
+                }
+                onClick={[Function]}
+              >
+                <WithStyles(ForwardRef(ButtonBase))
+                  aria-label="challenge.accessibility.button_slider_previous"
+                  centerRipple={true}
+                  className="MuiIconButton-root WithStyles(ForwardRef(IconButton))-root-1"
+                  disabled={false}
+                  focusRipple={true}
+                  onClick={[Function]}
+                >
+                  <ForwardRef(ButtonBase)
+                    aria-label="challenge.accessibility.button_slider_previous"
+                    centerRipple={true}
+                    className="MuiIconButton-root WithStyles(ForwardRef(IconButton))-root-1"
+                    classes={
+                      Object {
+                        "disabled": "Mui-disabled",
+                        "focusVisible": "Mui-focusVisible",
+                        "root": "MuiButtonBase-root",
+                      }
+                    }
+                    disabled={false}
+                    focusRipple={true}
+                    onClick={[Function]}
+                  >
+                    <button
+                      aria-label="challenge.accessibility.button_slider_previous"
+                      className="MuiButtonBase-root MuiIconButton-root WithStyles(ForwardRef(IconButton))-root-1"
+                      disabled={false}
+                      onBlur={[Function]}
+                      onClick={[Function]}
+                      onDragLeave={[Function]}
+                      onFocus={[Function]}
+                      onKeyDown={[Function]}
+                      onKeyUp={[Function]}
+                      onMouseDown={[Function]}
+                      onMouseLeave={[Function]}
+                      onMouseUp={[Function]}
+                      onTouchEnd={[Function]}
+                      onTouchMove={[Function]}
+                      onTouchStart={[Function]}
+                      tabIndex={0}
+                      type="button"
+                    >
+                      <span
+                        className="MuiIconButton-label"
+                      >
+                        <StyledIcon
+                          icon="test-file-stub"
+                          size={16}
+                        >
+                          <Icon
+                            aria-hidden={true}
+                            icon="test-file-stub"
+                            size={16}
+                            spin={false}
+                          >
+                            <Component
+                              aria-hidden={true}
+                              className="styles__icon___23x3R"
+                              height={16}
+                              style={Object {}}
+                              width={16}
+                            >
+                              <svg
+                                aria-hidden={true}
+                                className="styles__icon___23x3R"
+                                height={16}
+                                style={Object {}}
+                                width={16}
+                              >
+                                <use
+                                  xlinkHref="#test-file-stub"
+                                />
+                              </svg>
+                            </Component>
+                          </Icon>
+                        </StyledIcon>
+                      </span>
+                      <NoSsr>
+                        <WithStyles(memo)
+                          center={true}
+                        >
+                          <ForwardRef(TouchRipple)
+                            center={true}
+                            classes={
+                              Object {
+                                "child": "MuiTouchRipple-child",
+                                "childLeaving": "MuiTouchRipple-childLeaving",
+                                "childPulsate": "MuiTouchRipple-childPulsate",
+                                "ripple": "MuiTouchRipple-ripple",
+                                "ripplePulsate": "MuiTouchRipple-ripplePulsate",
+                                "rippleVisible": "MuiTouchRipple-rippleVisible",
+                                "root": "MuiTouchRipple-root",
+                              }
+                            }
+                          >
+                            <span
+                              className="MuiTouchRipple-root"
+                            >
+                              <TransitionGroup
+                                childFactory={[Function]}
+                                component={null}
+                                exit={true}
+                              />
+                            </span>
+                          </ForwardRef(TouchRipple)>
+                        </WithStyles(memo)>
+                      </NoSsr>
+                    </button>
+                  </ForwardRef(ButtonBase)>
+                </WithStyles(ForwardRef(ButtonBase))>
+              </ForwardRef(IconButton)>
+            </WithStyles(ForwardRef(IconButton))>
+          </WithStyles(WithStyles(ForwardRef(IconButton)))>
+        </StyledIconButton>
+        <StyledIconButton
+          aria-label="challenge.accessibility.button_slider_next"
+          icon="test-file-stub"
+          onClick={[Function]}
+          size={16}
+        >
+          <WithStyles(WithStyles(ForwardRef(IconButton)))
+            aria-label="challenge.accessibility.button_slider_next"
+            onClick={[Function]}
+          >
+            <WithStyles(ForwardRef(IconButton))
+              aria-label="challenge.accessibility.button_slider_next"
+              classes={
+                Object {
+                  "root": "WithStyles(ForwardRef(IconButton))-root-1",
+                }
+              }
+              onClick={[Function]}
+            >
+              <ForwardRef(IconButton)
+                aria-label="challenge.accessibility.button_slider_next"
+                classes={
+                  Object {
+                    "colorInherit": "MuiIconButton-colorInherit",
+                    "colorPrimary": "MuiIconButton-colorPrimary",
+                    "colorSecondary": "MuiIconButton-colorSecondary",
+                    "disabled": "Mui-disabled",
+                    "edgeEnd": "MuiIconButton-edgeEnd",
+                    "edgeStart": "MuiIconButton-edgeStart",
+                    "label": "MuiIconButton-label",
+                    "root": "MuiIconButton-root WithStyles(ForwardRef(IconButton))-root-1",
+                    "sizeSmall": "MuiIconButton-sizeSmall",
+                  }
+                }
+                onClick={[Function]}
+              >
+                <WithStyles(ForwardRef(ButtonBase))
+                  aria-label="challenge.accessibility.button_slider_next"
+                  centerRipple={true}
+                  className="MuiIconButton-root WithStyles(ForwardRef(IconButton))-root-1"
+                  disabled={false}
+                  focusRipple={true}
+                  onClick={[Function]}
+                >
+                  <ForwardRef(ButtonBase)
+                    aria-label="challenge.accessibility.button_slider_next"
+                    centerRipple={true}
+                    className="MuiIconButton-root WithStyles(ForwardRef(IconButton))-root-1"
+                    classes={
+                      Object {
+                        "disabled": "Mui-disabled",
+                        "focusVisible": "Mui-focusVisible",
+                        "root": "MuiButtonBase-root",
+                      }
+                    }
+                    disabled={false}
+                    focusRipple={true}
+                    onClick={[Function]}
+                  >
+                    <button
+                      aria-label="challenge.accessibility.button_slider_next"
+                      className="MuiButtonBase-root MuiIconButton-root WithStyles(ForwardRef(IconButton))-root-1"
+                      disabled={false}
+                      onBlur={[Function]}
+                      onClick={[Function]}
+                      onDragLeave={[Function]}
+                      onFocus={[Function]}
+                      onKeyDown={[Function]}
+                      onKeyUp={[Function]}
+                      onMouseDown={[Function]}
+                      onMouseLeave={[Function]}
+                      onMouseUp={[Function]}
+                      onTouchEnd={[Function]}
+                      onTouchMove={[Function]}
+                      onTouchStart={[Function]}
+                      tabIndex={0}
+                      type="button"
+                    >
+                      <span
+                        className="MuiIconButton-label"
+                      >
+                        <StyledIcon
+                          icon="test-file-stub"
+                          size={16}
+                        >
+                          <Icon
+                            aria-hidden={true}
+                            icon="test-file-stub"
+                            size={16}
+                            spin={false}
+                          >
+                            <Component
+                              aria-hidden={true}
+                              className="styles__icon___23x3R"
+                              height={16}
+                              style={Object {}}
+                              width={16}
+                            >
+                              <svg
+                                aria-hidden={true}
+                                className="styles__icon___23x3R"
+                                height={16}
+                                style={Object {}}
+                                width={16}
+                              >
+                                <use
+                                  xlinkHref="#test-file-stub"
+                                />
+                              </svg>
+                            </Component>
+                          </Icon>
+                        </StyledIcon>
+                      </span>
+                      <NoSsr>
+                        <WithStyles(memo)
+                          center={true}
+                        >
+                          <ForwardRef(TouchRipple)
+                            center={true}
+                            classes={
+                              Object {
+                                "child": "MuiTouchRipple-child",
+                                "childLeaving": "MuiTouchRipple-childLeaving",
+                                "childPulsate": "MuiTouchRipple-childPulsate",
+                                "ripple": "MuiTouchRipple-ripple",
+                                "ripplePulsate": "MuiTouchRipple-ripplePulsate",
+                                "rippleVisible": "MuiTouchRipple-rippleVisible",
+                                "root": "MuiTouchRipple-root",
+                              }
+                            }
+                          >
+                            <span
+                              className="MuiTouchRipple-root"
+                            >
+                              <TransitionGroup
+                                childFactory={[Function]}
+                                component={null}
+                                exit={true}
+                              />
+                            </span>
+                          </ForwardRef(TouchRipple)>
+                        </WithStyles(memo)>
+                      </NoSsr>
+                    </button>
+                  </ForwardRef(ButtonBase)>
+                </WithStyles(ForwardRef(ButtonBase))>
+              </ForwardRef(IconButton)>
+            </WithStyles(ForwardRef(IconButton))>
+          </WithStyles(WithStyles(ForwardRef(IconButton)))>
+        </StyledIconButton>
+      </div>
+    </mock-content>
+  </ChallengeView>
+</Provider>
 `;
diff --git a/src/components/Content/Content.tsx b/src/components/Content/Content.tsx
index 6e141e27364bfbdc739d623e8d636136fe291fef..0df5633eb4973f5c81f24fb70dbecdf68241ab84 100644
--- a/src/components/Content/Content.tsx
+++ b/src/components/Content/Content.tsx
@@ -1,13 +1,12 @@
 import React, { useCallback, useEffect } from 'react'
 import './content.scss'
-import { history } from 'components/App'
 import { useSelector, useDispatch } from 'react-redux'
 import { AppStore } from 'store'
 import { changeScreenType } from 'store/global/global.actions'
 import { updateModalIsFeedbacksOpen } from 'store/modal/modal.actions'
 import { ScreenType } from 'enum/screen.enum'
 import FeedbackModal from 'components/Feedback/FeedbackModal'
-
+import { useHistory } from 'react-router-dom'
 interface ContentProps {
   children?: React.ReactNode
   height?: number
@@ -20,6 +19,7 @@ const Content: React.FC<ContentProps> = ({
   background = 'inherit',
 }: ContentProps) => {
   const dispatch = useDispatch()
+  const history = useHistory()
   const { screenType } = useSelector((state: AppStore) => state.ecolyo.global)
   const { isFeedbacksOpen } = useSelector(
     (state: AppStore) => state.ecolyo.modal
@@ -38,10 +38,10 @@ const Content: React.FC<ContentProps> = ({
   /**
    * Handle Desktop scroll
    */
-  const handleWindowScroll = () => {
+  const handleWindowScroll = useCallback(() => {
     app && app.scrollTo(0, 0)
     window.scrollTo(0, 0)
-  }
+  }, [app])
 
   // Set listners for scroll
   useEffect(() => {
@@ -50,7 +50,7 @@ const Content: React.FC<ContentProps> = ({
       // remove listner subscription
       listner()
     }
-  }, [])
+  }, [handleWindowScroll, history])
 
   useEffect(() => {
     function handleResize() {
diff --git a/src/components/Duel/DuelView.spec.tsx b/src/components/Duel/DuelView.spec.tsx
index 5d6eece3cf01f26b9ecca538b2eec92301fc5c1f..f1fa4c7f1e9cb152f785a4f9ad7ed057a1b5fce6 100644
--- a/src/components/Duel/DuelView.spec.tsx
+++ b/src/components/Duel/DuelView.spec.tsx
@@ -10,6 +10,10 @@ import DuelUnlocked from './DuelUnlocked'
 import DuelOngoing from './DuelOngoing'
 import { UserDuelState } from 'enum/userDuel.enum'
 
+jest.mock('components/Header/CozyBar', () => 'mock-cozybar')
+jest.mock('components/Header/Header', () => 'mock-header')
+jest.mock('components/Content/Content', () => 'mock-content')
+
 const mockUseSelector = jest.spyOn(reactRedux, 'useSelector')
 
 describe('DuelView component', () => {
diff --git a/src/components/Ecogesture/EcogestureView.spec.tsx b/src/components/Ecogesture/EcogestureView.spec.tsx
index 0c7ab368b83f4f492036b88c08246bc8fe91195f..cc3aa53c2f1d236f4b98e0b595046c4f2fa0c2e5 100644
--- a/src/components/Ecogesture/EcogestureView.spec.tsx
+++ b/src/components/Ecogesture/EcogestureView.spec.tsx
@@ -1,4 +1,3 @@
-/* eslint-disable react/display-name */
 import React from 'react'
 import { mount } from 'enzyme'
 import { Provider } from 'react-redux'
diff --git a/src/components/Exploration/ExplorationView.spec.tsx b/src/components/Exploration/ExplorationView.spec.tsx
index afc90e3104495de4f9e48c1526640ed962d4b717..af8c18175b1be1c10018d36a4e447df74aaddaf1 100644
--- a/src/components/Exploration/ExplorationView.spec.tsx
+++ b/src/components/Exploration/ExplorationView.spec.tsx
@@ -8,19 +8,39 @@ import { challengeStateData } from '../../../tests/__mocks__/challengeStateData.
 import ExplorationFinished from './ExplorationFinished'
 import ExplorationError from './ExplorationError'
 import ExplorationOngoing from './ExplorationOngoing'
+import { UserExplorationState } from 'enum/userExploration.enum'
+
+jest.mock('components/Header/CozyBar', () => 'mock-cozybar')
+jest.mock('components/Header/Header', () => 'mock-header')
+jest.mock('components/Content/Content', () => 'mock-content')
 
 const mockUseSelector = jest.spyOn(reactRedux, 'useSelector')
 
 describe('ExplorationView', () => {
-  it('should be rendered with ExplorationView component when no exploration state', () => {
-    mockUseSelector.mockReturnValue(challengeStateData)
+  it('should be rendered with ExplorationError component when unknown exploration state', () => {
+    const updatedUserChallenge = {
+      ...userChallengeData[0],
+      exploration: {
+        ...userChallengeData[0].exploration,
+        state: 99,
+      },
+    }
+    const updatedChallengeState = {
+      ...challengeStateData,
+      currentChallenge: updatedUserChallenge,
+    }
+    mockUseSelector.mockReturnValue(updatedChallengeState)
     const wrapper = shallow(<ExplorationView />)
-    expect(wrapper.find(ExplorationError).exists())
+    expect(wrapper.find(ExplorationError).exists()).toBeTruthy()
   })
-  it('should be rendered with ExplorationView component when exploration state = unlocked', () => {
+
+  it('should be rendered with ExplorationOngoing component when exploration state = unlocked', () => {
     const updatedUserChallenge = {
       ...userChallengeData[0],
-      quiz: { ...userChallengeData[0].quiz, state: UserQuizState.UNLOCKED },
+      exploration: {
+        ...userChallengeData[0].exploration,
+        state: UserExplorationState.UNLOCKED,
+      },
     }
     const updatedChallengeState = {
       ...challengeStateData,
@@ -28,12 +48,16 @@ describe('ExplorationView', () => {
     }
     mockUseSelector.mockReturnValue(updatedChallengeState)
     const wrapper = shallow(<ExplorationView />)
-    expect(wrapper.find(ExplorationOngoing).exists())
+    expect(wrapper.find(ExplorationOngoing).exists()).toBeTruthy()
   })
-  it('should be rendered with ExplorationView component when exploration state = ongoing', () => {
+
+  it('should be rendered with ExplorationOngoing component when exploration state = ongoing', () => {
     const updatedUserChallenge = {
       ...userChallengeData[0],
-      quiz: { ...userChallengeData[0].quiz, state: UserQuizState.ONGOING },
+      exploration: {
+        ...userChallengeData[0].exploration,
+        state: UserExplorationState.ONGOING,
+      },
     }
     const updatedChallengeState = {
       ...challengeStateData,
@@ -41,12 +65,16 @@ describe('ExplorationView', () => {
     }
     mockUseSelector.mockReturnValue(updatedChallengeState)
     const wrapper = shallow(<ExplorationView />)
-    expect(wrapper.find(ExplorationOngoing).exists())
+    expect(wrapper.find(ExplorationOngoing).exists()).toBeTruthy()
   })
-  it('should be rendered with ExplorationView component when exploration state = Done', () => {
+
+  it('should be rendered with ExplorationFinished component when exploration state = Done', () => {
     const updatedUserChallenge = {
       ...userChallengeData[0],
-      quiz: { ...userChallengeData[0].quiz, state: UserQuizState.DONE },
+      exploration: {
+        ...userChallengeData[0].exploration,
+        state: UserExplorationState.DONE,
+      },
     }
     const updatedChallengeState = {
       ...challengeStateData,
@@ -54,6 +82,6 @@ describe('ExplorationView', () => {
     }
     mockUseSelector.mockReturnValue(updatedChallengeState)
     const wrapper = shallow(<ExplorationView />)
-    expect(wrapper.find(ExplorationFinished).exists())
+    expect(wrapper.find(ExplorationFinished).exists()).toBeTruthy()
   })
 })
diff --git a/src/components/FAQ/FAQView.spec.tsx b/src/components/FAQ/FAQView.spec.tsx
index 0cf009bf050a365e30a9e57b179ffbe328304f2f..74f74ef60abcb520e3ff5571e0c85389b725583b 100644
--- a/src/components/FAQ/FAQView.spec.tsx
+++ b/src/components/FAQ/FAQView.spec.tsx
@@ -11,6 +11,9 @@ jest.mock('cozy-ui/transpiled/react/I18n', () => {
     }),
   }
 })
+jest.mock('components/Header/CozyBar', () => 'mock-cozybar')
+jest.mock('components/Header/Header', () => 'mock-header')
+jest.mock('components/Content/Content', () => 'mock-content')
 
 describe('FAQView component', () => {
   it('should render only the parent component', () => {
diff --git a/src/components/FAQ/__snapshots__/FAQView.spec.tsx.snap b/src/components/FAQ/__snapshots__/FAQView.spec.tsx.snap
index d39d3478bcca7a209cdf08cfc7eb3e8ee35366f1..285ef8a29c5ce9475e1167d5d092bfd17c0099e4 100644
--- a/src/components/FAQ/__snapshots__/FAQView.spec.tsx.snap
+++ b/src/components/FAQ/__snapshots__/FAQView.spec.tsx.snap
@@ -1,20 +1,20 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`FAQView component should render only the parent component 1`] = `
-<React.Fragment>
-  <CozyBar
-    displayBackArrow={true}
-    titleKey="common.title_faq"
-  />
-  <Header
-    desktopTitleKey="common.title_faq"
-    displayBackArrow={true}
-    setHeaderHeight={[Function]}
-  />
-  <Content
-    height={0}
-  >
-    <FAQContent />
-  </Content>
-</React.Fragment>
-`;
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`FAQView component should render only the parent component 1`] = `
+<React.Fragment>
+  <mock-cozybar
+    displayBackArrow={true}
+    titleKey="common.title_faq"
+  />
+  <mock-header
+    desktopTitleKey="common.title_faq"
+    displayBackArrow={true}
+    setHeaderHeight={[Function]}
+  />
+  <mock-content
+    height={0}
+  >
+    <FAQContent />
+  </mock-content>
+</React.Fragment>
+`;
diff --git a/src/components/GCU/GCUView.spec.tsx b/src/components/GCU/GCUView.spec.tsx
index 809feee5f8f215e804951195b91b10e2448ca2a3..6ede9dbdc54199016cf3717f459440d15105735f 100644
--- a/src/components/GCU/GCUView.spec.tsx
+++ b/src/components/GCU/GCUView.spec.tsx
@@ -2,6 +2,10 @@ import React from 'react'
 import { shallow } from 'enzyme'
 import GCUView from 'components/GCU/GCUView'
 
+jest.mock('components/Header/CozyBar', () => 'mock-cozybar')
+jest.mock('components/Header/Header', () => 'mock-header')
+jest.mock('components/Content/Content', () => 'mock-content')
+
 describe('GCUView component', () => {
   it('should be rendered correctly', () => {
     const component = shallow(<GCUView />).getElement()
diff --git a/src/components/GCU/__snapshots__/GCUView.spec.tsx.snap b/src/components/GCU/__snapshots__/GCUView.spec.tsx.snap
index 33e490ab2cee7cf73924e66f7e9dfaed67e42d16..bcc93b8a7020797f0037ffa7d0db41ef8be7f3e6 100644
--- a/src/components/GCU/__snapshots__/GCUView.spec.tsx.snap
+++ b/src/components/GCU/__snapshots__/GCUView.spec.tsx.snap
@@ -2,19 +2,19 @@
 
 exports[`GCUView component should be rendered correctly 1`] = `
 <React.Fragment>
-  <CozyBar
+  <mock-cozybar
     displayBackArrow={true}
     titleKey="common.title_gcu"
   />
-  <Header
+  <mock-header
     desktopTitleKey="common.title_gcu"
     displayBackArrow={true}
     setHeaderHeight={[Function]}
   />
-  <Content
+  <mock-content
     height={0}
   >
     <GCUContent />
-  </Content>
+  </mock-content>
 </React.Fragment>
 `;
diff --git a/src/components/Home/ConsumptionView.spec.tsx b/src/components/Home/ConsumptionView.spec.tsx
index a272d2bf25de666933374873ca1bbaec1ffd4698..1692736e7d99cba2e99ac6a3701b00b80cf215bf 100644
--- a/src/components/Home/ConsumptionView.spec.tsx
+++ b/src/components/Home/ConsumptionView.spec.tsx
@@ -1,4 +1,3 @@
-/* eslint-disable react/display-name */
 import React from 'react'
 import { mount } from 'enzyme'
 import { Provider } from 'react-redux'
@@ -12,6 +11,8 @@ import * as chartActions from 'store/chart/chart.actions'
 import { FluidState, FluidType } from 'enum/fluid.enum'
 import { TimeStep } from 'enum/timeStep.enum'
 import StyledSpinner from 'components/CommonKit/Spinner/StyledSpinner'
+import FluidButtons from 'components/Home/FluidButtons'
+import KonnectorViewerList from 'components/Konnector/KonnectorViewerList'
 import ConsumptionView from './ConsumptionView'
 import { FluidStatus } from 'models'
 import { mockTestProfile1 } from '../../../tests/__mocks__/profileType.mock'
@@ -77,6 +78,7 @@ describe('ConsumptionView component', () => {
       loading: false,
       fluidStatus: mockFluidStatus,
       releaseNotes: mockInitialEcolyoState.global.releaseNotes,
+      openPartnersIssueModal: false,
     })
     const wrapper = mount(
       <Provider store={store}>
@@ -100,6 +102,7 @@ describe('ConsumptionView component', () => {
       loading: true,
       fluidStatus: mockFluidStatus,
       releaseNotes: mockInitialEcolyoState.global.releaseNotes,
+      openPartnersIssueModal: false,
     })
     const wrapper = mount(
       <Provider store={store}>
@@ -118,6 +121,7 @@ describe('ConsumptionView component', () => {
       loading: true,
       fluidStatus: mockInitialEcolyoState.global.fluidStatus,
       releaseNotes: mockInitialEcolyoState.global.releaseNotes,
+      openPartnersIssueModal: false,
     })
     mount(
       <Provider store={store}>
@@ -127,12 +131,14 @@ describe('ConsumptionView component', () => {
     expect(setCurrentTimeStepSpy).toBeCalledTimes(1)
     expect(setCurrentTimeStepSpy).toHaveBeenCalledWith(TimeStep.WEEK)
   })
+
   it('should render konnector list when no fluid is connected', () => {
     useSelectorSpy.mockReturnValue({
       currentTimeStep: TimeStep.WEEK,
       loading: true,
       fluidStatus: mockInitialEcolyoState.global.fluidStatus,
       releaseNotes: mockInitialEcolyoState.global.releaseNotes,
+      openPartnersIssueModal: false,
     })
     const wrapper = mount(
       <Provider store={store}>
@@ -141,6 +147,7 @@ describe('ConsumptionView component', () => {
     )
     expect(wrapper.find('mock-consumptiondetails').exists()).toBeTruthy()
   })
+
   it('should render mutlifluid consumption if at least one fluid is connected', () => {
     const updatedStatus: FluidStatus[] =
       mockInitialEcolyoState.global.fluidStatus
@@ -151,6 +158,7 @@ describe('ConsumptionView component', () => {
       loading: true,
       fluidStatus: updatedStatus,
       releaseNotes: mockInitialEcolyoState.global.releaseNotes,
+      openPartnersIssueModal: false,
     })
     const wrapper = mount(
       <Provider store={store}>
@@ -159,6 +167,7 @@ describe('ConsumptionView component', () => {
     )
     expect(wrapper.find('.consumptionview-content').exists()).toBeTruthy()
   })
+
   it('should render Electricity when elec is connected', () => {
     const updatedStatus: FluidStatus[] =
       mockInitialEcolyoState.global.fluidStatus
@@ -168,6 +177,7 @@ describe('ConsumptionView component', () => {
       loading: true,
       fluidStatus: updatedStatus,
       releaseNotes: mockInitialEcolyoState.global.releaseNotes,
+      openPartnersIssueModal: false,
     })
     const wrapper = mount(
       <Provider store={store}>
diff --git a/src/components/LegalNotice/LegalNoticeView.spec.tsx b/src/components/LegalNotice/LegalNoticeView.spec.tsx
index d63efac8a14437c8c49ad0e10b4cd91f33940459..2c3c35247f8254d480c68843e29cc04757bb8d5e 100644
--- a/src/components/LegalNotice/LegalNoticeView.spec.tsx
+++ b/src/components/LegalNotice/LegalNoticeView.spec.tsx
@@ -2,6 +2,10 @@ import React from 'react'
 import { shallow } from 'enzyme'
 import LegalNoticeView from 'components/LegalNotice/LegalNoticeView'
 
+jest.mock('components/Header/CozyBar', () => 'mock-cozybar')
+jest.mock('components/Header/Header', () => 'mock-header')
+jest.mock('components/Content/Content', () => 'mock-content')
+
 describe('LegalNoticeView component', () => {
   it('should be rendered correctly', () => {
     const component = shallow(<LegalNoticeView />).getElement()
diff --git a/src/components/LegalNotice/__snapshots__/LegalNoticeView.spec.tsx.snap b/src/components/LegalNotice/__snapshots__/LegalNoticeView.spec.tsx.snap
index 50fb84232368727f90e205ec6ade27e17ca50ca2..52b42634ccd99ef5cc0458c03738dcb536858289 100644
--- a/src/components/LegalNotice/__snapshots__/LegalNoticeView.spec.tsx.snap
+++ b/src/components/LegalNotice/__snapshots__/LegalNoticeView.spec.tsx.snap
@@ -2,19 +2,19 @@
 
 exports[`LegalNoticeView component should be rendered correctly 1`] = `
 <React.Fragment>
-  <CozyBar
+  <mock-cozybar
     displayBackArrow={true}
     titleKey="common.title_legal_notice"
   />
-  <Header
+  <mock-header
     desktopTitleKey="common.title_legal_notice"
     displayBackArrow={true}
     setHeaderHeight={[Function]}
   />
-  <Content
+  <mock-content
     height={0}
   >
     <LegalNoticeContent />
-  </Content>
+  </mock-content>
 </React.Fragment>
 `;
diff --git a/src/components/Options/MatomoOptOut.spec.tsx b/src/components/Options/MatomoOptOut.spec.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..11ca220012806d180ab8d95272e65ad1679325d2
--- /dev/null
+++ b/src/components/Options/MatomoOptOut.spec.tsx
@@ -0,0 +1,20 @@
+import React from 'react'
+import { shallow } from 'enzyme'
+import { MatomoOptOut } from './MatomoOptOut'
+
+jest.mock('cozy-ui/transpiled/react/I18n', () => {
+  return {
+    useI18n: jest.fn(() => {
+      return {
+        t: (str: string) => str,
+      }
+    }),
+  }
+})
+
+describe('MatomoOptOut component', () => {
+  it('should be rendered correctly', () => {
+    const component = shallow(<MatomoOptOut />).getElement()
+    expect(component).toMatchSnapshot()
+  })
+})
diff --git a/src/components/Options/MatomoOptOut.tsx b/src/components/Options/MatomoOptOut.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..69e16ae49cc8eca9e7897a869c213e541d36ac5a
--- /dev/null
+++ b/src/components/Options/MatomoOptOut.tsx
@@ -0,0 +1,24 @@
+import React from 'react'
+import { useI18n } from 'cozy-ui/transpiled/react/I18n'
+import './matomoOptOut.scss'
+
+declare let __PIWIK_TRACKER_URL__: string
+
+export const MatomoOptOut: React.FC = () => {
+  const { t } = useI18n()
+  const baseUrl = __PIWIK_TRACKER_URL__
+
+  return (
+    <div className="matomo-opt-out-container">
+      <div className="matomo-opt-out">
+        <div className="opt-out-header text-16-normal-uppercase">
+          {t('matomo.matomo_title')}
+        </div>
+        <iframe
+          style={{ height: '250px' }}
+          src={`${baseUrl}index.php?module=CoreAdminHome&action=optOut&language=fr&backgroundColor=121212&fontColor=e0e0e0&fontSize=&fontFamily=sans-serif`}
+        ></iframe>
+      </div>
+    </div>
+  )
+}
diff --git a/src/components/Options/OptionsView.spec.tsx b/src/components/Options/OptionsView.spec.tsx
index a1fc5688d7e559de5cd87cf117d7ac545217cb88..0f2f73c8d8ff3cec0c7882d4425683ba66266c7e 100644
--- a/src/components/Options/OptionsView.spec.tsx
+++ b/src/components/Options/OptionsView.spec.tsx
@@ -2,9 +2,12 @@ import React from 'react'
 import { shallow } from 'enzyme'
 import OptionsView from 'components/Options/OptionsView'
 
+jest.mock('components/Header/CozyBar', () => 'mock-cozybar')
+jest.mock('components/Header/Header', () => 'mock-header')
+jest.mock('components/Content/Content', () => 'mock-content')
 jest.mock(
   'components/Konnector/KonnectorViewerList',
-  () => 'KonnectorViewerList'
+  () => 'mock-konnectorviewerlist'
 )
 
 describe('OptionsView component', () => {
diff --git a/src/components/Options/OptionsView.tsx b/src/components/Options/OptionsView.tsx
index a6fb18867dd2b948369bd0bd0a1ecec6c7fc5f33..906e5c209d0978b3b12c1675201476e4b29c103b 100644
--- a/src/components/Options/OptionsView.tsx
+++ b/src/components/Options/OptionsView.tsx
@@ -10,6 +10,7 @@ import Version from 'components/Version/Version'
 import ProfileTypeOptions from './ProfileTypeOptions'
 
 import logos from 'assets/png/logos.png'
+import { MatomoOptOut } from './MatomoOptOut'
 
 const OptionsView: React.FC = () => {
   const [headerHeight, setHeaderHeight] = useState<number>(0)
@@ -29,6 +30,7 @@ const OptionsView: React.FC = () => {
         <FAQLink />
         <LegalNoticeLink />
         <GCULink />
+        <MatomoOptOut />
         <div className="parameters-logos">
           <img src={logos} alt="ensemble de logos" />
         </div>
diff --git a/src/components/Options/UnSubscribe.spec.tsx b/src/components/Options/UnSubscribe.spec.tsx
index e77f60d6a8a88b94a347005ed2aaf50a70ac364b..bd7b90d4697e2b2ef304a4aa301fd30d4544b1a1 100644
--- a/src/components/Options/UnSubscribe.spec.tsx
+++ b/src/components/Options/UnSubscribe.spec.tsx
@@ -1,5 +1,6 @@
 import React from 'react'
 import { mount } from 'enzyme'
+import toJson from 'enzyme-to-json'
 import { Provider } from 'react-redux'
 import {
   createMockStore,
@@ -18,6 +19,9 @@ jest.mock('cozy-ui/transpiled/react/I18n', () => {
     }),
   }
 })
+jest.mock('components/Header/CozyBar', () => 'mock-cozybar')
+jest.mock('components/Header/Header', () => 'mock-header')
+jest.mock('components/Content/Content', () => 'mock-content')
 
 const mockUpdateProfile = jest.fn()
 jest.mock('services/profile.service', () => {
@@ -27,7 +31,6 @@ jest.mock('services/profile.service', () => {
     }
   })
 })
-// const useDispatchSpy = jest.spyOn(reactRedux, 'useDispatch')
 const updateProfileSpy = jest.spyOn(profileActions, 'updateProfile')
 
 describe('UnSubscribe component', () => {
@@ -43,8 +46,8 @@ describe('UnSubscribe component', () => {
       <Provider store={store}>
         <UnSubscribe />
       </Provider>
-    ).getElement()
-    expect(wrapper).toMatchSnapshot()
+    )
+    expect(toJson(wrapper)).toMatchSnapshot()
   })
 
   it('should click on button and deactivate report', () => {
diff --git a/src/components/Options/__snapshots__/MatomoOptOut.spec.tsx.snap b/src/components/Options/__snapshots__/MatomoOptOut.spec.tsx.snap
new file mode 100644
index 0000000000000000000000000000000000000000..599b28c0a472fe9b02fd1b93dc448c2b6e597659
--- /dev/null
+++ b/src/components/Options/__snapshots__/MatomoOptOut.spec.tsx.snap
@@ -0,0 +1,25 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`MatomoOptOut component should be rendered correctly 1`] = `
+<div
+  className="matomo-opt-out-container"
+>
+  <div
+    className="matomo-opt-out"
+  >
+    <div
+      className="opt-out-header text-16-normal-uppercase"
+    >
+      matomo.matomo_title
+    </div>
+    <iframe
+      src="http://localhost:9800/index.php?module=CoreAdminHome&action=optOut&language=fr&backgroundColor=121212&fontColor=e0e0e0&fontSize=&fontFamily=sans-serif"
+      style={
+        Object {
+          "height": "250px",
+        }
+      }
+    />
+  </div>
+</div>
+`;
diff --git a/src/components/Options/__snapshots__/OptionsView.spec.tsx.snap b/src/components/Options/__snapshots__/OptionsView.spec.tsx.snap
index a77207e38365d2469fe2a4384dff0645f4ad9872..3cdb93ecb9ac5e5207444fe7bc45111e528e874e 100644
--- a/src/components/Options/__snapshots__/OptionsView.spec.tsx.snap
+++ b/src/components/Options/__snapshots__/OptionsView.spec.tsx.snap
@@ -2,14 +2,14 @@
 
 exports[`OptionsView component should be rendered correctly 1`] = `
 <React.Fragment>
-  <CozyBar
+  <mock-cozybar
     titleKey="common.title_options"
   />
-  <Header
+  <mock-header
     desktopTitleKey="common.title_options"
     setHeaderHeight={[Function]}
   />
-  <Content
+  <mock-content
     height={0}
   >
     <ProfileTypeOptions />
@@ -17,6 +17,7 @@ exports[`OptionsView component should be rendered correctly 1`] = `
     <FAQLink />
     <LegalNoticeLink />
     <GCULink />
+    <MatomoOptOut />
     <div
       className="parameters-logos"
     >
@@ -26,6 +27,6 @@ exports[`OptionsView component should be rendered correctly 1`] = `
       />
     </div>
     <Version />
-  </Content>
+  </mock-content>
 </React.Fragment>
 `;
diff --git a/src/components/Options/__snapshots__/UnSubscribe.spec.tsx.snap b/src/components/Options/__snapshots__/UnSubscribe.spec.tsx.snap
index fc7a7ac6793887011529c6731c5460c3afba29f7..850bd82974778a1d842aeabab509cb128275115f 100644
--- a/src/components/Options/__snapshots__/UnSubscribe.spec.tsx.snap
+++ b/src/components/Options/__snapshots__/UnSubscribe.spec.tsx.snap
@@ -13,6 +13,202 @@ exports[`UnSubscribe component should be rendered correctly 1`] = `
     }
   }
 >
-  <UnSubscribe />
+  <UnSubscribe>
+    <mock-cozybar
+      titleKey="common.title_analysis"
+    />
+    <mock-header
+      desktopTitleKey="common.title_analysis"
+      setHeaderHeight={[Function]}
+    />
+    <mock-content
+      height={0}
+    >
+      <div
+        className="unsubscribe-container"
+      >
+        <StyledIcon
+          className="profile-icon"
+          icon="test-file-stub"
+          size={250}
+        >
+          <Icon
+            aria-hidden={true}
+            className="profile-icon"
+            icon="test-file-stub"
+            size={250}
+            spin={false}
+          >
+            <Component
+              aria-hidden={true}
+              className="profile-icon styles__icon___23x3R"
+              height={250}
+              style={Object {}}
+              width={250}
+            >
+              <svg
+                aria-hidden={true}
+                className="profile-icon styles__icon___23x3R"
+                height={250}
+                style={Object {}}
+                width={250}
+              >
+                <use
+                  xlinkHref="#test-file-stub"
+                />
+              </svg>
+            </Component>
+          </Icon>
+        </StyledIcon>
+        <div
+          className="text-20-bold head"
+        >
+          unsubscribe.title
+        </div>
+        <div
+          className="text-16-normal question"
+        >
+          unsubscribe.content
+        </div>
+        <WithStyles(ForwardRef(Button))
+          aria-label="unsubscribe.button_accessibility"
+          classes={
+            Object {
+              "label": "text-18-bold",
+              "root": "btn-highlight",
+            }
+          }
+          onClick={[Function]}
+          type="submit"
+          variant="contained"
+        >
+          <ForwardRef(Button)
+            aria-label="unsubscribe.button_accessibility"
+            classes={
+              Object {
+                "colorInherit": "MuiButton-colorInherit",
+                "contained": "MuiButton-contained",
+                "containedPrimary": "MuiButton-containedPrimary",
+                "containedSecondary": "MuiButton-containedSecondary",
+                "containedSizeLarge": "MuiButton-containedSizeLarge",
+                "containedSizeSmall": "MuiButton-containedSizeSmall",
+                "disableElevation": "MuiButton-disableElevation",
+                "disabled": "Mui-disabled",
+                "endIcon": "MuiButton-endIcon",
+                "focusVisible": "Mui-focusVisible",
+                "fullWidth": "MuiButton-fullWidth",
+                "iconSizeLarge": "MuiButton-iconSizeLarge",
+                "iconSizeMedium": "MuiButton-iconSizeMedium",
+                "iconSizeSmall": "MuiButton-iconSizeSmall",
+                "label": "MuiButton-label text-18-bold",
+                "outlined": "MuiButton-outlined",
+                "outlinedPrimary": "MuiButton-outlinedPrimary",
+                "outlinedSecondary": "MuiButton-outlinedSecondary",
+                "outlinedSizeLarge": "MuiButton-outlinedSizeLarge",
+                "outlinedSizeSmall": "MuiButton-outlinedSizeSmall",
+                "root": "MuiButton-root btn-highlight",
+                "sizeLarge": "MuiButton-sizeLarge",
+                "sizeSmall": "MuiButton-sizeSmall",
+                "startIcon": "MuiButton-startIcon",
+                "text": "MuiButton-text",
+                "textPrimary": "MuiButton-textPrimary",
+                "textSecondary": "MuiButton-textSecondary",
+                "textSizeLarge": "MuiButton-textSizeLarge",
+                "textSizeSmall": "MuiButton-textSizeSmall",
+              }
+            }
+            onClick={[Function]}
+            type="submit"
+            variant="contained"
+          >
+            <WithStyles(ForwardRef(ButtonBase))
+              aria-label="unsubscribe.button_accessibility"
+              className="MuiButton-root btn-highlight MuiButton-contained"
+              component="button"
+              disabled={false}
+              focusRipple={true}
+              focusVisibleClassName="Mui-focusVisible"
+              onClick={[Function]}
+              type="submit"
+            >
+              <ForwardRef(ButtonBase)
+                aria-label="unsubscribe.button_accessibility"
+                className="MuiButton-root btn-highlight MuiButton-contained"
+                classes={
+                  Object {
+                    "disabled": "Mui-disabled",
+                    "focusVisible": "Mui-focusVisible",
+                    "root": "MuiButtonBase-root",
+                  }
+                }
+                component="button"
+                disabled={false}
+                focusRipple={true}
+                focusVisibleClassName="Mui-focusVisible"
+                onClick={[Function]}
+                type="submit"
+              >
+                <button
+                  aria-label="unsubscribe.button_accessibility"
+                  className="MuiButtonBase-root MuiButton-root btn-highlight MuiButton-contained"
+                  disabled={false}
+                  onBlur={[Function]}
+                  onClick={[Function]}
+                  onDragLeave={[Function]}
+                  onFocus={[Function]}
+                  onKeyDown={[Function]}
+                  onKeyUp={[Function]}
+                  onMouseDown={[Function]}
+                  onMouseLeave={[Function]}
+                  onMouseUp={[Function]}
+                  onTouchEnd={[Function]}
+                  onTouchMove={[Function]}
+                  onTouchStart={[Function]}
+                  tabIndex={0}
+                  type="submit"
+                >
+                  <span
+                    className="MuiButton-label text-18-bold"
+                  >
+                    unsubscribe.button_text
+                  </span>
+                  <NoSsr>
+                    <WithStyles(memo)
+                      center={false}
+                    >
+                      <ForwardRef(TouchRipple)
+                        center={false}
+                        classes={
+                          Object {
+                            "child": "MuiTouchRipple-child",
+                            "childLeaving": "MuiTouchRipple-childLeaving",
+                            "childPulsate": "MuiTouchRipple-childPulsate",
+                            "ripple": "MuiTouchRipple-ripple",
+                            "ripplePulsate": "MuiTouchRipple-ripplePulsate",
+                            "rippleVisible": "MuiTouchRipple-rippleVisible",
+                            "root": "MuiTouchRipple-root",
+                          }
+                        }
+                      >
+                        <span
+                          className="MuiTouchRipple-root"
+                        >
+                          <TransitionGroup
+                            childFactory={[Function]}
+                            component={null}
+                            exit={true}
+                          />
+                        </span>
+                      </ForwardRef(TouchRipple)>
+                    </WithStyles(memo)>
+                  </NoSsr>
+                </button>
+              </ForwardRef(ButtonBase)>
+            </WithStyles(ForwardRef(ButtonBase))>
+          </ForwardRef(Button)>
+        </WithStyles(ForwardRef(Button))>
+      </div>
+    </mock-content>
+  </UnSubscribe>
 </Provider>
 `;
diff --git a/src/components/Options/matomoOptOut.scss b/src/components/Options/matomoOptOut.scss
new file mode 100644
index 0000000000000000000000000000000000000000..184e9e44e3ae351ae99a80537907fc0d187336bc
--- /dev/null
+++ b/src/components/Options/matomoOptOut.scss
@@ -0,0 +1,27 @@
+@import 'src/styles/base/color';
+@import 'src/styles/base/breakpoint';
+@import 'src/styles/base/typo-variables';
+
+.matomo-opt-out-container {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  padding: 0 1.5rem;
+  margin: 1rem 0;
+
+  .matomo-opt-out {
+    margin: 0 auto;
+    width: 100%;
+    @media (min-width: $width-large-phone) {
+      width: 45.75rem;
+    }
+    .opt-out-header {
+      color: $grey-bright;
+    }
+
+    * {
+      font-family: $text-font;
+    }
+  }
+}
diff --git a/src/components/ProfileType/ProfileTypeView.spec.tsx b/src/components/ProfileType/ProfileTypeView.spec.tsx
index 8bc1460237445aa465f15481260e1b57c212fe8f..8c3385e1fa77235043a1e3834d89ff02ee0c2d4e 100644
--- a/src/components/ProfileType/ProfileTypeView.spec.tsx
+++ b/src/components/ProfileType/ProfileTypeView.spec.tsx
@@ -2,9 +2,6 @@ import React from 'react'
 import { Provider } from 'react-redux'
 import { mount } from 'enzyme'
 import ProfileTypeView from 'components/ProfileType/ProfileTypeView'
-import CozyBar from 'components/Header/CozyBar'
-import Header from 'components/Header/Header'
-import Content from 'components/Content/Content'
 import {
   createMockStore,
   mockInitialEcolyoState,
@@ -20,6 +17,10 @@ jest.mock('cozy-ui/transpiled/react/I18n', () => {
   }
 })
 
+jest.mock('components/Header/CozyBar', () => 'mock-cozybar')
+jest.mock('components/Header/Header', () => 'mock-header')
+jest.mock('components/Content/Content', () => 'mock-content')
+
 describe('ProfileTypeView component', () => {
   // eslint-disable-next-line @typescript-eslint/no-explicit-any
   let store: any
@@ -33,8 +34,9 @@ describe('ProfileTypeView component', () => {
         <ProfileTypeView />
       </Provider>
     )
-    expect(wrapper.find(CozyBar)).toBeTruthy()
-    expect(wrapper.find(Header)).toBeTruthy()
-    expect(wrapper.find(Content)).toBeTruthy()
+    expect(wrapper.find('mock-cozybar').exists()).toBeTruthy()
+    expect(wrapper.find('mock-header').exists()).toBeTruthy()
+    expect(wrapper.find('mock-content').exists()).toBeTruthy()
+    expect(wrapper.find('.profile-type-container').exists()).toBeTruthy()
   })
 })
diff --git a/src/components/ProfileType/ProfileTypeView.tsx b/src/components/ProfileType/ProfileTypeView.tsx
index 8d43c4f1f7d9fd414e75fe17013e87be23ce6bcb..545ce04c328a2d26d4151b142c38eadd6f33bdde 100644
--- a/src/components/ProfileType/ProfileTypeView.tsx
+++ b/src/components/ProfileType/ProfileTypeView.tsx
@@ -16,11 +16,11 @@ import {
   IndividualOrCollective,
   OutsideFacingWalls,
   ProfileTypeFormType,
+  ProfileTypeStepForm,
   ThreeChoicesAnswer,
   WarmingType,
 } from 'enum/profileType.enum'
 import { FluidType } from 'enum/fluid.enum'
-import { ProfileTypeStepForm } from 'enum/profileType.enum'
 import ProfileTypeFormMultiChoice from 'components/ProfileType/ProfileTypeFormMultiChoice'
 import ProfileTypeFormNumber from 'components/ProfileType/ProfileTypeFormNumber'
 import ProfileTypeFormNumberSelection from 'components/ProfileType/ProfileTypeFormNumberSelection'
diff --git a/src/components/Quiz/QuizView.spec.tsx b/src/components/Quiz/QuizView.spec.tsx
index 788a3fe499b68a9c211c1af83ea4a0db598ee6f2..fec5d9281ee4e4946d4f495562293e9b79611645 100644
--- a/src/components/Quiz/QuizView.spec.tsx
+++ b/src/components/Quiz/QuizView.spec.tsx
@@ -9,6 +9,9 @@ import QuizBegin from './QuizBegin'
 import QuizQuestion from './QuizQuestion'
 import QuizFinish from './QuizFinish'
 
+jest.mock('components/Header/CozyBar', () => 'mock-cozybar')
+jest.mock('components/Header/Header', () => 'mock-header')
+jest.mock('components/Content/Content', () => 'mock-content')
 const mockUseSelector = jest.spyOn(reactRedux, 'useSelector')
 
 describe('QuizView component', () => {
@@ -23,7 +26,7 @@ describe('QuizView component', () => {
     }
     mockUseSelector.mockReturnValue(updatedChallengeState)
     const wrapper = shallow(<QuizView />)
-    expect(wrapper.find(QuizBegin).exists())
+    expect(wrapper.find(QuizBegin).exists()).toBeTruthy()
   })
 
   it('should be rendered with QuizQuestion component when quiz state = ongoing', () => {
@@ -37,7 +40,7 @@ describe('QuizView component', () => {
     }
     mockUseSelector.mockReturnValue(updatedChallengeState)
     const wrapper = shallow(<QuizView />)
-    expect(wrapper.find(QuizQuestion).exists())
+    expect(wrapper.find(QuizQuestion).exists()).toBeTruthy()
   })
 
   it('should be rendered with QuizFinish component when quiz state = done', () => {
@@ -51,7 +54,7 @@ describe('QuizView component', () => {
     }
     mockUseSelector.mockReturnValue(updatedChallengeState)
     const wrapper = shallow(<QuizView />)
-    expect(wrapper.find(QuizFinish).exists())
+    expect(wrapper.find(QuizFinish).exists()).toBeTruthy()
   })
 
   it('should be rendered with QuizBegin component when quiz state = null', () => {
@@ -65,6 +68,6 @@ describe('QuizView component', () => {
     }
     mockUseSelector.mockReturnValue(updatedChallengeState)
     const wrapper = shallow(<QuizView />)
-    expect(wrapper.find(QuizBegin).exists())
+    expect(wrapper.find(QuizBegin).exists()).toBeTruthy()
   })
 })
diff --git a/src/locales/fr.json b/src/locales/fr.json
index beadc6d1271d583b241af1f5b7a438399aeb3118..390739d587ab11cb46fbbfeaae259d8d3587815b 100644
--- a/src/locales/fr.json
+++ b/src/locales/fr.json
@@ -676,6 +676,9 @@
     "title": "Conditions générales d’utilisation",
     "read_gcu": "Lire les CGU"
   },
+  "matomo": {
+    "matomo_title": "Suivi statistiques d'usage Matomo"
+  },
   "header": {
     "accessibility": {
       "button_back": "Retour à la page précédente",
diff --git a/src/services/environment.service.ts b/src/services/environment.service.ts
index 0fb89f8f4f67c7ba49f64e067885c293c33c708c..116c1bcc9e0e09afbb2128774fdb9710927f33a8 100644
--- a/src/services/environment.service.ts
+++ b/src/services/environment.service.ts
@@ -1,4 +1,5 @@
 declare const __IS_ALPHA__: boolean
+declare const __DEVELOPMENT__: boolean
 
 export default class EnvironmentService {
   private isAlpha() {
@@ -21,4 +22,8 @@ export default class EnvironmentService {
       return 'https://ecolyo-agent-rec.grandlyon.com'
     }
   }
+
+  public isLocal() {
+    return __DEVELOPMENT__
+  }
 }
diff --git a/src/targets/browser/index.ejs b/src/targets/browser/index.ejs
index 3f5bf59a4e99894939c462c357c162ffc64e53de..a30958e2e1852957cfaf60fe21636ceb27c1ee43 100644
--- a/src/targets/browser/index.ejs
+++ b/src/targets/browser/index.ejs
@@ -28,25 +28,19 @@
     {{.ThemeCSS}}
 
     <% if (__TARGET__ === 'mobile') { %>
-
     <meta name="format-detection" content="telephone=no">
     <script src="cordova.js" defer></script>
     <% } else if (__STACK_ASSETS__) { %>
     {{.CozyBar}}
     <% } %>
+    <script src="//{{.Domain}}/assets/js/piwik.js"></script>
+
   </head>
   <body>
   <div
     role="application"
     class="application"
-    data-cozy-token="{{.Token}}"
-    data-cozy-domain="{{.Domain}}"
-    data-cozy-locale="{{.Locale}}"
-    data-cozy-app-name="{{.AppName}}"
-    data-cozy-app-slug="{{.AppSlug}}"
-    data-cozy-app-name-prefix="{{.AppNamePrefix}}"
-    data-cozy-app-editor="{{.AppEditor}}"
-    data-cozy-icon-path="{{.IconPath}}"
+    data-cozy="{{.CozyData}}"
   >
   <% _.forEach(htmlWebpackPlugin.files.js, function(file) { %>
       <script src="<%- file %>"></script>
diff --git a/src/targets/browser/index.tsx b/src/targets/browser/index.tsx
index 8337a39baad8bfb532f840e769e8d0dd119ebc8a..93fcbc519c14ef21dabe8e3e9b6e99c24f0a4516 100644
--- a/src/targets/browser/index.tsx
+++ b/src/targets/browser/index.tsx
@@ -1,50 +1,91 @@
 /* eslint-disable @typescript-eslint/no-explicit-any */
 /* eslint-disable @typescript-eslint/no-var-requires */
 /* global cozy */
+declare let cozy: any
+declare let __PIWIK_TRACKER_URL__: string
+declare let __PIWIK_SITEID__: number
+declare let Piwik: any
+
 import '../../styles/index.scss'
 
 import React from 'react'
 import { render } from 'react-dom'
-import { Client, CozyProvider } from 'cozy-client'
+import CozyClient, { Client, CozyProvider } from 'cozy-client'
 import { Provider } from 'react-redux'
 import configureStore from 'store'
 import { I18n, initTranslation } from 'cozy-ui/transpiled/react/I18n'
 import { handleOAuthResponse } from 'cozy-harvest-lib/dist/helpers/oauth'
 import { memoize } from 'lodash'
-import { getClient } from '../../utils/client'
-import { getValues, initBar } from '../../utils/bar'
+import manifest from '../../../manifest.webapp'
+import schema from 'doctypes'
+import { createBrowserHistory, History } from 'history'
+import { HashRouter } from 'react-router-dom'
+import MatomoTracker from 'utils/matomoTracker'
 
 const setupApp = memoize(() => {
+  const history: History = createBrowserHistory()
+  // eslint-disable-next-line @typescript-eslint/no-explicit-any
   const root: any = document.querySelector('[role=application]')
-  const { lang }: any = getValues(root.dataset)
-  const polyglot: any = initTranslation(lang, lang =>
+  const data = JSON.parse(root.dataset.cozy)
+  const protocol = window.location.protocol
+  const cozyUrl = `${protocol}//${data.domain}`
+
+  const locale = 'fr'
+  const polyglot: any = initTranslation(locale, lang =>
     require(`locales/${lang}`)
   )
-  const client: Client = getClient()
+
+  const client: Client = new CozyClient({
+    uri: cozyUrl,
+    token: data.token,
+    appMetadata: {
+      slug: manifest.name,
+      version: manifest.version,
+    },
+    schema,
+  })
+
   const persistedState: any = {}
   const store: any = configureStore(client, persistedState)
 
-  /** I don't know why I need to for this... But if I don't it seems that
-   * we have a race between configureStore and initBar resulting in
-   * an error from cozy-client "store is already defined"
-   */
-  setTimeout(() => {
-    initBar(client)
-  }, 0)
+  cozy.bar.init({
+    appName: data.app.name,
+    appEditor: data.app.editor,
+    cozyClient: client,
+    iconPath: data.app.icon,
+    lang: data.locale,
+    replaceTitleOnMobile: false,
+    appSlug: data.app.slug,
+    appNamePrefix: data.app.prefix,
+  })
+
+  let tracker
+  if (window.Piwik) {
+    Piwik.getTracker()
+    tracker = new MatomoTracker({
+      cozyUrl: cozyUrl,
+      url: __PIWIK_TRACKER_URL__,
+      siteId: __PIWIK_SITEID__,
+      history: history,
+      phpFilename: 'matomo.php',
+    })
+  }
 
-  return { root, store, client, lang, polyglot }
+  return { root, store, client, locale, polyglot, history, tracker }
 })
 
 const init = () => {
-  const { root, store, client, lang, polyglot } = setupApp()
+  const { root, store, client, locale, polyglot, history, tracker } = setupApp()
 
   if (handleOAuthResponse()) return
   const App = require('components/App').default
   render(
     <Provider store={store}>
       <CozyProvider client={client}>
-        <I18n lang={lang} polyglot={polyglot}>
-          <App />
+        <I18n lang={locale} polyglot={polyglot}>
+          <HashRouter {...history}>
+            <App tracker={tracker} />
+          </HashRouter>
         </I18n>
       </CozyProvider>
     </Provider>,
diff --git a/src/targets/vendor/assets/serviceWorker.js b/src/targets/vendor/assets/serviceWorker.js
index ba1c298b71463c33d43cc121b0d7485026e0efa8..0f14f5b13d69bb7fad30392b70a118150352a9ce 100644
--- a/src/targets/vendor/assets/serviceWorker.js
+++ b/src/targets/vendor/assets/serviceWorker.js
@@ -12,6 +12,10 @@ self.addEventListener('install', event => {
 
 // Listen for requests
 self.addEventListener('fetch', event => {
+  if (event.request.url.indexOf('statweb') !== -1) {
+    return false
+  }
+
   event.respondWith(
     caches.match(event.request).then(() => {
       return fetch(event.request).catch(() => caches.match('offline.html'))
diff --git a/src/types/cozy-ui.d.ts b/src/types/cozy-ui.d.ts
index 01a043d2956e291ddb1bc827f34429d86713bbb8..a13bfbd3f043d8493ea441d5efba5c0b0cce5896 100644
--- a/src/types/cozy-ui.d.ts
+++ b/src/types/cozy-ui.d.ts
@@ -3,6 +3,7 @@
 declare module 'cozy-ui/transpiled/react/Icon'
 declare module 'cozy-ui/transpiled/react/Spinner'
 declare module 'cozy-ui/transpiled/react/Layout'
+declare module 'cozy-ui/transpiled/react/helpers/appDataset'
 
 declare module 'cozy-ui/transpiled/react/I18n' {
   interface IPropsIcon {
diff --git a/src/types/custom.d.ts b/src/types/custom.d.ts
index 0016563a7edbf81abbfd0a222b69e62df2fe09a1..7112effa625990e5b6011188a0044ae5092e2bc6 100644
--- a/src/types/custom.d.ts
+++ b/src/types/custom.d.ts
@@ -6,3 +6,5 @@ declare module '*.svg' {
   const content: string
   export default content
 }
+
+declare module '*.webapp'
diff --git a/src/utils/bar.ts b/src/utils/bar.ts
deleted file mode 100644
index ef818bc84febba6e66c2679cad8757dc5d03404e..0000000000000000000000000000000000000000
--- a/src/utils/bar.ts
+++ /dev/null
@@ -1,59 +0,0 @@
-/* eslint-disable @typescript-eslint/no-explicit-any */
-/* global cozy */
-
-import { Client } from 'cozy-client'
-import manifest from '../../manifest.webapp'
-
-interface GetValues {
-  cozyAppName: string
-  cozyAppNamePrefix: string
-  cozyIconPath: string
-  cozyLocale: string
-}
-
-const getDataOrDefault = (data: any, defaultData: any) =>
-  /^\{\{\..*\}\}$/.test(data) ? defaultData : data //NOSONAR
-
-/**
- * default data will allow to display correctly the cozy-bar
- * in the standalone (without cozy-stack connexion)
- */
-export const getValues = ({
-  cozyAppName,
-  cozyAppNamePrefix,
-  cozyIconPath,
-}: GetValues) => {
-  const defaultValues = {
-    appIconDefault: require('../targets/vendor/assets/icon.svg'),
-    appNamePrefixDefault: manifest.name_prefix,
-    appNameDefault: manifest.name,
-    appLocaleDefault: 'fr',
-  }
-  return {
-    appName: getDataOrDefault(cozyAppName, defaultValues.appNameDefault),
-    appNamePrefix: getDataOrDefault(
-      cozyAppNamePrefix,
-      defaultValues.appNamePrefixDefault
-    ),
-    iconPath: getDataOrDefault(cozyIconPath, defaultValues.appIconDefault),
-    lang: defaultValues.appLocaleDefault,
-  }
-}
-
-/**
- * Cozy bar initialization
- * @param {object} client - cozy client
- */
-export const initBar = (client: Client) => {
-  const root: any = document.querySelector('[role=application]')
-  const { appName, appNamePrefix, iconPath, lang } = getValues(root.dataset)
-
-  cozy.bar.init({
-    appName,
-    appNamePrefix,
-    cozyClient: client,
-    iconPath,
-    lang,
-    replaceTitleOnMobile: false,
-  })
-}
diff --git a/src/utils/client.ts b/src/utils/client.ts
deleted file mode 100644
index c5826f38a39df570686911072fd7fc45220d73ff..0000000000000000000000000000000000000000
--- a/src/utils/client.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import CozyClient from 'cozy-client'
-import manifest from '../../manifest.webapp'
-import schema from 'doctypes'
-
-/**
- * Returns cozy client instance
- * @returns {object} cozy client instance
- */
-export const getClient = () => {
-  // eslint-disable-next-line @typescript-eslint/no-explicit-any
-  const root: any = document.querySelector('[role=application]')
-  const data = root.dataset
-  const protocol = window.location.protocol
-  const cozyUrl = `${protocol}//${data.cozyDomain}`
-
-  return new CozyClient({
-    uri: cozyUrl,
-    token: data.cozyToken,
-    appMetadata: {
-      slug: manifest.name,
-      version: manifest.version,
-    },
-    schema,
-  })
-}
diff --git a/src/utils/matomoTracker.ts b/src/utils/matomoTracker.ts
new file mode 100644
index 0000000000000000000000000000000000000000..1afb34486aa3badd66f427661e23e9ef838ed56b
--- /dev/null
+++ b/src/utils/matomoTracker.ts
@@ -0,0 +1,109 @@
+import { History, Location, UnregisterCallback } from 'history'
+import { readCozyDataFromDOM } from 'cozy-ui/transpiled/react/helpers/appDataset'
+
+interface InitSettings {
+  cozyUrl: string
+  url: string
+  siteId: number
+  history: History
+  phpFilename?: string
+}
+
+declare global {
+  interface Window {
+    _paq: any
+    Piwik: any
+  }
+}
+
+export default class MatomoTracker {
+  cozyUrl: string
+  url: string
+  siteId: number
+  phpFilename: string
+  history: History
+  unlistenFromHistory: UnregisterCallback
+
+  constructor({
+    cozyUrl,
+    url,
+    siteId,
+    history,
+    phpFilename = 'matomo.php',
+  }: InitSettings) {
+    if (url === undefined || siteId === undefined) {
+      throw new Error(
+        'MatomoTracker cannot be initialized! SiteId and url are mandatory.'
+      )
+    }
+    this.cozyUrl = cozyUrl
+    this.url = url
+    this.siteId = siteId
+    this.phpFilename = phpFilename
+    this.history = history
+    this.unlistenFromHistory = () => null
+    this.init()
+  }
+
+  init() {
+    if (typeof window !== 'undefined') {
+      window._paq = window._paq || []
+      MatomoTracker.push(['enableHeartBeatTimer', 30])
+      MatomoTracker.push(['setSiteId', this.siteId])
+      MatomoTracker.push(['setReferrerUrl', 'https://ecolyo.com'])
+      MatomoTracker.push(['setTrackerUrl', `${this.url + this.phpFilename}`])
+      MatomoTracker.push(['enableLinkTracking'])
+    }
+    return {
+      push: MatomoTracker.push,
+      track: this.track,
+      connectToHistory: this.connectToHistory,
+      disconnectFromHistory: this.disconnectFromHistory,
+    }
+  }
+
+  static push(args: (number[] | string[] | number | string)[]) {
+    window._paq.push(args)
+  }
+
+  configure() {
+    let cozyDomain
+    let userId
+    const root: any = document.querySelector('[role=application]')
+    if (root && root.dataset) {
+      cozyDomain = readCozyDataFromDOM('cozyDomain')
+    }
+    if (cozyDomain) {
+      userId = cozyDomain
+      const indexOfPort = cozyDomain.indexOf(':')
+      if (indexOfPort >= 0) {
+        userId = userId.substring(0, indexOfPort)
+      }
+    }
+  }
+
+  connectToHistory() {
+    this.unlistenFromHistory = this.history.listen(loc => {
+      this.track(loc)
+    })
+  }
+
+  disconnectFromHistory() {
+    if (this.unlistenFromHistory) {
+      this.unlistenFromHistory()
+      return true
+    }
+    return false
+  }
+
+  track(loc: Location) {
+    if (typeof window === 'undefined') {
+      return
+    }
+    const currentPath = loc.hash.substring(1)
+
+    MatomoTracker.push(['setDocumentTitle', currentPath.substring(1)])
+    MatomoTracker.push(['setCustomUrl', 'https://ecolyo.com' + currentPath])
+    MatomoTracker.push(['trackPageView'])
+  }
+}