diff --git a/src/components/feature/FeatureListTable.vue b/src/components/feature/FeatureListTable.vue
index 2787cb177a7096722f862dfe21b194c5bcf96216..dfba1b87b37cd5777d577bf6c5c9d0bc09068156 100644
--- a/src/components/feature/FeatureListTable.vue
+++ b/src/components/feature/FeatureListTable.vue
@@ -237,7 +237,7 @@ export default {
   name: "FeatureListTable",
 
   props: [
-    "geojsonFeatures",
+    "paginatedFeatures",
     "checkedFeatures",
     "featuresCount",
     "pagination",
@@ -262,7 +262,7 @@ export default {
     },
 
     sortedFeatures() {
-      let sortedFeatures = [...this.geojsonFeatures];
+      let sortedFeatures = [...this.paginatedFeatures];
       // Ajout du tri
       if (this.sort.column !== "") {
         sortedFeatures = sortedFeatures.sort((a, b) => {
diff --git a/src/services/feature-api.js b/src/services/feature-api.js
index e9a02215c3a9f855c376e8ccf357d722fd63355d..3618c8687cd360acd707e991b6f8bd050e5768c7 100644
--- a/src/services/feature-api.js
+++ b/src/services/feature-api.js
@@ -1,9 +1,39 @@
-import axios from 'axios';
+import axios from "@/axios-client.js";
 import store from '../store'
 
 const baseUrl = store.state.configuration.VUE_APP_DJANGO_API_BASE;
 
 const featureAPI = {
+  async getFeaturesBbox(project_slug, queryParams) {
+    const response = await axios.get(
+      `${baseUrl}projects/${project_slug}/feature-bbox/${queryParams ? '?' + queryParams : ""}`
+    );
+    if (
+      response.status === 200 &&
+      response.data
+    ) {
+      const bbox = response.data;
+      return [
+        [bbox[2], bbox[3]],
+        [bbox[0], bbox[1]],
+      ];
+    } else {
+      return null;
+    }
+  },
+
+  async getPaginatedFeatures(url) {
+    const response = await axios.get(url);
+    if (
+      response.status === 200 &&
+      response.data
+    ) {
+      return response.data;
+    } else {
+      return null;
+    }
+  },
+
   async getFeatureEvents(featureId) {
     const response = await axios.get(
       `${baseUrl}features/${featureId}/events/`
diff --git a/src/views/feature/Feature_list.vue b/src/views/feature/Feature_list.vue
index 1bb24d0fbc731c81422a92f8ed244ce03e499798..408091df72d8955bc4a332ddd4fef83f14128038 100644
--- a/src/views/feature/Feature_list.vue
+++ b/src/views/feature/Feature_list.vue
@@ -1,6 +1,5 @@
 <template>
   <div class="fourteen wide column">
-    
     <div id="feature-list-container" class="ui grid mobile-column">
       <div class="four wide column mobile-fullwidth">
         <h1>Signalements</h1>
@@ -16,7 +15,7 @@
             ><i class="map fitted icon"></i
           ></a>
           <a
-            @click="showTable"
+            @click="showMap = false"
             :class="['item no-margin', { active: !showMap }]"
             data-tab="list"
             data-tooltip="Liste"
@@ -24,10 +23,10 @@
           ></a>
           <div class="item">
             <h4>
-              <!-- {{ featuresCount }} signalement{{ featuresCount > 1 ? "s" : "" }} -->
-              {{ filteredFeatures.length }} signalement{{
+              {{ featuresCount }} signalement{{ featuresCount > 1 ? "s" : "" }}
+              <!-- {{ filteredFeatures.length }} signalement{{
                 filteredFeatures.length > 1 ? "s" : ""
-              }}
+              }} -->
             </h4>
           </div>
 
@@ -83,12 +82,12 @@
       </div>
     </div>
 
-    <form id="form-filters" class="ui form grid" action="" method="get">
+    <section id="form-filters" class="ui form grid">
       <div class="field wide four column no-margin-mobile">
         <label>Type</label>
         <Dropdown
           v-on:update:selection="updateTypeFeatures"
-          :options="form.type.choices"
+          :options="featureTypeChoices"
           :selected="form.type.selected"
           :selection.sync="form.type.selected"
           :search="true"
@@ -116,12 +115,12 @@
               type="text"
               name="title"
               v-model="form.title"
-              @input="fetchPagedFeatures"
+              v-on:keyup.enter="fetchPagedFeatures"
             />
             <button
-              type="button"
-              class="ui teal icon button"
+              @click="fetchPagedFeatures"
               id="submit-search"
+              class="ui teal icon button"
             >
               <i class="search icon"></i>
             </button>
@@ -132,7 +131,7 @@
       <input type="hidden" name="zoom" v-model="zoom" />
       <input type="hidden" name="lat" v-model="lat" />
       <input type="hidden" name="lng" v-model="lng" />
-    </form>
+    </section>
 
     <div v-show="showMap" class="ui tab active map-container" data-tab="map">
       <div id="map" ref="map"></div>
@@ -142,7 +141,7 @@
     <FeatureListTable
       v-show="!showMap"
       v-on:update:page="handlePageChange"
-      :geojsonFeatures="geojsonFeaturesPaginated"
+      :paginatedFeatures="paginatedFeatures"
       :checkedFeatures.sync="checkedFeatures"
       :featuresCount="featuresCount"
       :pagination="pagination"
@@ -185,17 +184,12 @@
 <script>
 import { mapGetters, mapState } from "vuex";
 import { mapUtil } from "@/assets/js/map-util.js";
+import featureAPI from "@/services/feature-api";
 import SidebarLayers from "@/components/map-layers/SidebarLayers";
 import FeatureListTable from "@/components/feature/FeatureListTable";
 import Dropdown from "@/components/Dropdown.vue";
 import axios from "@/axios-client.js";
 
-// axios.defaults.headers.common['X-CSRFToken'] = (name => {
-//   var re = new RegExp(name + "=([^;]+)");
-//   var value = re.exec(document.cookie);
-//   return (value !== null) ? unescape(value[1]) : null;
-// })('csrftoken');
-
 export default {
   name: "Feature_list",
 
@@ -239,30 +233,23 @@ export default {
         },
         title: null,
       },
-
-      geojsonFeatures: [],
-      geojsonFeaturesPaginated: [],
+      paginatedFeatures: [],
       baseUrl: this.$store.state.configuration.BASE_URL,
       map: null,
       zoom: null,
       lat: null,
       lng: null,
-      //limit: 15,
-      //offset: 0,
       featuresCount: 0,
-      filterType: null,
-      filterStatus: null,
+      next: null,
+      previous: null,
       pagination: {
         currentPage: 1,
         pagesize: 15,
         start: 0,
         end: 15,
       },
-      previous: null,
-      next: null,
       showMap: true,
       showAddFeature: false,
-      paginatedFeaturesDone: true,
     };
   },
 
@@ -283,6 +270,10 @@ export default {
       );
     },
 
+    featureTypeChoices() {
+      return this.feature_types.map((el) => el.title);
+    },
+
     pageNumbers() {
       const totalPages = Math.ceil(
         this.featuresCount / this.pagination.pagesize
@@ -292,51 +283,9 @@ export default {
         return pageNumb;
       });
     },
-
-    filteredFeatures() {
-      let results = this.geojsonFeatures;
-      if (this.form.type.selected) {
-        results = results.filter(
-          (el) => el.properties.feature_type.title === this.form.type.selected
-        );
-      }
-      if (this.form.status.selected.value) {
-        console.log("filter by" + this.form.status.selected.value);
-        results = results.filter(
-          (el) => el.properties.status.value === this.form.status.selected.value
-        );
-      }
-      if (this.form.title) {
-        results = results.filter((el) => {
-          if (el.properties.title) {
-            return el.properties.title
-              .toLowerCase()
-              .includes(this.form.title.toLowerCase());
-          } else
-            return el.id.toLowerCase().includes(this.form.title.toLowerCase());
-        });
-      }
-      return results;
-    },
-  },
-
-  watch: {
-    filteredFeatures(newValue, oldValue) {
-      if (newValue && newValue !== oldValue) {
-        this.onFilterChange();
-      }
-    },
   },
 
   methods: {
-    showTable() {
-      if (this.paginatedFeaturesDone) {
-        this.fetchPagedFeatures();
-        this.paginatedFeaturesDone = false;
-      }
-      this.showMap = false;
-    },
-
     modalAllDelete() {
       this.modalAllDeleteOpen = !this.modalAllDeleteOpen;
     },
@@ -373,28 +322,12 @@ export default {
     },
 
     onFilterChange() {
-      if (this.featureGroup) {
-        const features = this.filteredFeatures;
-        this.featureGroup.clearLayers();
-        this.featureGroup = mapUtil.addFeatures(
-          features,
-          {},
-          true,
-          this.feature_types
-        );
+      if (mapUtil.getMap()) {
         mapUtil.getMap().invalidateSize();
         mapUtil.getMap()._onResize(); // force refresh for vector tiles
-        if(window.layerMVT) {
+        if (window.layerMVT) {
           window.layerMVT.redraw();
         }
-        
-        if (this.featureGroup.getLayers().length > 0) {
-          mapUtil
-            .getMap()
-            .fitBounds(this.featureGroup.getBounds(), { padding: [25, 25] });
-        } else {
-          mapUtil.getMap().zoomOut(1);
-        }
       }
     },
 
@@ -416,6 +349,8 @@ export default {
         mapDefaultViewZoom,
       });
 
+      this.getBbox2FIt();
+
       document.addEventListener("change-layers-order", (event) => {
         // Reverse is done because the first layer in order has to be added in the map in last.
         // Slice is done because reverse() changes the original array, so we make a copy first
@@ -423,8 +358,6 @@ export default {
       });
 
       // --------- End sidebar events ----------
-      //this.fetchPagedFeatures();
-      this.getNloadGeojsonFeatures();
 
       setTimeout(() => {
         const project_id = this.$route.params.slug.split("-")[0];
@@ -439,59 +372,16 @@ export default {
       }, 1000);
     },
 
-    getNloadGeojsonFeatures() {
-      const url = `${this.$store.state.configuration.VUE_APP_DJANGO_API_BASE}projects/${this.$route.params.slug}/feature/?output=geojson`;
-      this.$store.commit(
-        "DISPLAY_LOADER",
-        "Récupération des signalements en cours..."
-      );
-      axios
-        .get(url)
-        .then((response) => {
-          if (response.status === 200 && response.data.features.length > 0) {
-            this.geojsonFeatures = response.data.features;
-            this.loadFeatures();
+    getBbox2FIt(queryParams) {
+      featureAPI
+        .getFeaturesBbox(this.project.slug, queryParams)
+        .then((bbox) => {
+          if (bbox) {
+            mapUtil.getMap().fitBounds(bbox, { padding: [25, 25] });
           }
-          this.$store.commit("DISCARD_LOADER");
-        })
-        .catch((error) => {
-          this.$store.commit("DISCARD_LOADER");
-          throw error;
         });
     },
 
-    loadFeatures() {
-      const urlParams = new URLSearchParams(window.location.search);
-      const featureType = urlParams.get("feature_type");
-      const featureStatus = urlParams.get("status");
-      const featureTitle = urlParams.get("title");
-      this.featureGroup = mapUtil.addFeatures(
-        this.geojsonFeatures,
-        {
-          featureType,
-          featureStatus,
-          featureTitle,
-        },
-        true,
-        this.feature_types
-      );
-      // Fit the map to bound only if no initial zoom and center are defined
-      if (
-        (this.lat === "" || this.lng === "" || this.zoom === "") &&
-        this.geojsonFeatures.length > 0
-      ) {
-        mapUtil
-          .getMap()
-          .fitBounds(this.featureGroup.getBounds(), { padding: [25, 25] });
-      }
-      this.form.type.choices = [
-        //* converting Set to an Array with spread "..."
-        ...new Set(
-          this.geojsonFeatures.map((el) => el.properties.feature_type.title)
-        ), //* use Set to eliminate duplicate values
-      ];
-    },
-
     //* Paginated Features for table *//
     getFeatureTypeSlug(title) {
       const featureType = this.feature_types.find((el) => el.title === title);
@@ -549,7 +439,7 @@ export default {
       if (this.form.title) {
         params += `&title=${this.form.title}`;
       }
-
+      this.getBbox2FIt(params);
       return params;
     },
 
@@ -564,8 +454,7 @@ export default {
     },
 
     fetchPagedFeatures(params) {
-      // this.onFilterChange(); //* temporary, use paginated event to watch change in filters, to modify geojson on map
-      //* replace function calls in watcher and on input
+      this.onFilterChange(); //* temporary, use paginated event to watch change in filters, to modify geojson on map
       let url = `${this.API_BASE_URL}projects/${this.$route.params.slug}/feature-paginated/?output=geojson&limit=${this.pagination.pagesize}&offset=${this.pagination.start}`;
 
       if (params) {
@@ -575,8 +464,7 @@ export default {
           url += filterParams;
         } else {
           //console.error("ONLY FOR DEV !!!!!!!!!!!!!");
-          //params = params.replace("8000", "8010");
-          //console.log(url);
+          //params = params.replace("8000", "8010"); //* for dev uncomment to use proxy link
           url = params;
         }
       }
@@ -585,25 +473,15 @@ export default {
         "DISPLAY_LOADER",
         "Récupération des signalements en cours..."
       );
-      axios
-        .get(url)
-        .then((response) => {
-          if (response.status === 200) {
-            this.featuresCount = response.data.count;
-            this.previous = response.data.previous;
-            this.next = response.data.next;
-            this.geojsonFeaturesPaginated = response.data.results.features;
-            //if (response.data.results.features.length > 0) {
-            //this.loadFeatures();
-            //this.onFilterChange();
-            //}
-          }
-          this.$store.commit("DISCARD_LOADER");
-        })
-        .catch((error) => {
-          this.$store.commit("DISCARD_LOADER");
-          throw error;
-        });
+      featureAPI.getPaginatedFeatures(url).then((data) => {
+        if (data) {
+          this.featuresCount = data.count;
+          this.previous = data.previous;
+          this.next = data.next;
+          this.paginatedFeatures = data.results.features;
+        }
+        this.$store.commit("DISCARD_LOADER");
+      });
     },
 
     //* Pagination for table *//
@@ -656,12 +534,11 @@ export default {
       // Chargements des features et infos projet en cas d'arrivée directe sur la page ou de refresh
       this.$store
         .dispatch("GET_PROJECT_INFO", this.$route.params.slug)
-        .then(() => {
-          this.initMap();
-        });
+        .then(() => this.initMap());
     } else {
       this.initMap();
     }
+    this.fetchPagedFeatures();
   },
 
   destroyed() {
diff --git a/src/views/project/Project_detail.vue b/src/views/project/Project_detail.vue
index 3d5a04b4f3a5cae82d95a2a01126765ab6c7fff6..a521510dafccaec62c0d38b68930b86e4f4d8773 100644
--- a/src/views/project/Project_detail.vue
+++ b/src/views/project/Project_detail.vue
@@ -406,7 +406,8 @@
                     >
                       <div class="content">
                         <div>
-                          <router-link :to="getRouteUrl(item.related_feature.feature_url)"
+                          <router-link
+                            :to="getRouteUrl(item.related_feature.feature_url)"
                             >"{{ item.comment }}"</router-link
                           >
                         </div>
@@ -550,14 +551,9 @@ import frag from "vue-frag";
 import { mapUtil } from "@/assets/js/map-util.js";
 import { mapGetters, mapState } from "vuex";
 import projectAPI from "@/services/project-api";
+import featureAPI from "@/services/feature-api";
 
-import axios from '@/axios-client.js';
-
-// axios.defaults.headers.common['X-CSRFToken'] = (name => {
-//   var re = new RegExp(name + "=([^;]+)");
-//   var value = re.exec(document.cookie);
-//   return (value !== null) ? unescape(value[1]) : null;
-// })('csrftoken');
+import axios from "@/axios-client.js";
 
 export default {
   name: "Project_details",
@@ -617,8 +613,8 @@ export default {
     refreshId() {
       return "?ver=" + Math.random();
     },
-    getRouteUrl(url){
-      return '/'+url.replace(this.$store.state.configuration.BASE_URL,''); // remove duplicate /geocontrib
+    getRouteUrl(url) {
+      return "/" + url.replace(this.$store.state.configuration.BASE_URL, ""); // remove duplicate /geocontrib
     },
     isOffline() {
       return navigator.onLine === false;
@@ -755,7 +751,6 @@ export default {
     initMap() {
       if (this.project && this.permissions.can_view_project) {
         this.$store.dispatch("map/INITIATE_MAP", this.$refs.map);
-        const url = `${this.API_BASE_URL}projects/${this.$route.params.slug}/feature/?output=geojson`;
         this.checkForOfflineFeature();
         let project_id = this.$route.params.slug.split("-")[0];
         const mvtUrl = `${this.API_BASE_URL}features.mvt/?tile={z}/{x}/{y}&project_id=${project_id}`;
@@ -764,34 +759,22 @@ export default {
           this.$route.params.slug,
           this.$store.state.feature_type.feature_types
         );
-        axios
-          .get(url)
-          .then((response) => {
-            let features = response.data.features;
-            this.arraysOffline.forEach(
-              (x) => (x.geojson.properties.color = "red")
-            );
-            features = response.data.features.concat(
-              this.arraysOffline.map((x) => x.geojson)
-            );
-            const featureGroup = mapUtil.addFeatures(
-              features,
-              {},
-              true,
-              this.$store.state.feature_type.feature_types
-            );
-
-            if (featureGroup && featureGroup.getLayers().length > 0) {
-              mapUtil
-                .getMap()
-                .fitBounds(featureGroup.getBounds(), { padding: [25, 25] });
-              this.$store.commit("map/SET_GEOJSON_FEATURES", features);
-            } else {
-              this.$store.commit("map/SET_GEOJSON_FEATURES", []);
+
+        this.arraysOffline.forEach((x) => (x.geojson.properties.color = "red"));
+        const features = this.arraysOffline.map((x) => x.geojson);
+        mapUtil.addFeatures(
+          features,
+          {},
+          true,
+          this.$store.state.feature_type.feature_types
+        );
+
+        featureAPI
+          .getFeaturesBbox(this.project.slug)
+          .then((bbox) => {
+            if (bbox) {
+              mapUtil.getMap().fitBounds(bbox, { padding: [25, 25] });
             }
-          })
-          .catch((error) => {
-            throw error;
           });
       }
     },
@@ -807,14 +790,14 @@ export default {
   },
 
   mounted() {
-    this.$store.dispatch('GET_PROJECT_INFO', this.slug)
-      .then(() => {
-        this.featureTypeLoading = false;
-        setTimeout(this.initMap, 1000);
-      });
-    this.$store.dispatch('feature/GET_PROJECT_FEATURES', {
-      project_slug: this.slug
-    })
+    this.$store.dispatch("GET_PROJECT_INFO", this.slug).then(() => {
+      this.featureTypeLoading = false;
+      setTimeout(this.initMap, 1000);
+    });
+    this.$store
+      .dispatch("feature/GET_PROJECT_FEATURES", {
+        project_slug: this.slug,
+      })
       .then(() => {
         this.featuresLoading = false;
       });
@@ -888,4 +871,4 @@ export default {
 .text-left {
   text-align: left !important;
 }
-</style>
\ No newline at end of file
+</style>