diff --git a/src/services/feature-api.js b/src/services/feature-api.js
index 82ee94bcbec1005f3ef14a067e3bbddc74d1bd8a..bfabc583d85386be69d43928e1e319e16315b3d6 100644
--- a/src/services/feature-api.js
+++ b/src/services/feature-api.js
@@ -1,10 +1,10 @@
 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 baseUrl = store.state.configuration.VUE_APP_DJANGO_API_BASE;
     const response = await axios.get(
       `${baseUrl}projects/${project_slug}/feature-bbox/${queryParams ? '?' + queryParams : ''}`
     );
@@ -22,6 +22,21 @@ const featureAPI = {
     }
   },
 
+  async getProjectFeature(project_slug, feature_id) {
+    const baseUrl = store.state.configuration.VUE_APP_DJANGO_API_BASE;
+    const response = await axios.get(
+      `${baseUrl}v2/features/${feature_id}/?project__slug=${project_slug}`
+    );
+    if (
+      response.status === 200 &&
+      response.data
+    ) {
+      return response.data;
+    } else {
+      return null;
+    }
+  },
+
   async getPaginatedFeatures(url) {
     const response = await axios.get(url);
     if (
@@ -35,6 +50,7 @@ const featureAPI = {
   },
 
   async getFeatureEvents(featureId) {
+    const baseUrl = store.state.configuration.VUE_APP_DJANGO_API_BASE;
     const response = await axios.get(
       `${baseUrl}features/${featureId}/events/`
     );
@@ -49,6 +65,7 @@ const featureAPI = {
   },
 
   async getFeatureAttachments(featureId) {
+    const baseUrl = store.state.configuration.VUE_APP_DJANGO_API_BASE;
     const response = await axios.get(
       `${baseUrl}features/${featureId}/attachments/`
     );
@@ -63,6 +80,7 @@ const featureAPI = {
   },
 
   async getFeatureLinks(featureId) {
+    const baseUrl = store.state.configuration.VUE_APP_DJANGO_API_BASE;
     const response = await axios.get(
       `${baseUrl}features/${featureId}/feature-links/`
     );
@@ -92,6 +110,7 @@ const featureAPI = {
 
 
   async postOrPutFeature({ method, feature_id, feature_type__slug, project__slug, data }) {
+    const baseUrl = store.state.configuration.VUE_APP_DJANGO_API_BASE;
     let url = `${baseUrl}v2/features/`;
     if (method === 'PUT') {
       url += `${feature_id}/?
@@ -112,6 +131,7 @@ const featureAPI = {
   },
 
   async updateFeature({ feature_id, feature_type__slug, project__slug, newStatus }) {
+    const baseUrl = store.state.configuration.VUE_APP_DJANGO_API_BASE;
     const url = `${baseUrl}features/${feature_id}/?feature_type__slug=${feature_type__slug}&project__slug=${project__slug}`;
 
     const response = await axios({
@@ -127,6 +147,7 @@ const featureAPI = {
   },
 
   async postComment({ featureId, comment }) {
+    const baseUrl = store.state.configuration.VUE_APP_DJANGO_API_BASE;
     const response = await axios.post(
       `${baseUrl}features/${featureId}/comments/`, { comment }
     );
@@ -141,6 +162,7 @@ const featureAPI = {
   },
 
   async postCommentAttachment({ featureId, file, fileName, commentId, title }) {
+    const baseUrl = store.state.configuration.VUE_APP_DJANGO_API_BASE;
     const formdata = new FormData();
     formdata.append('file', file, fileName);
     formdata.append('title', title);
diff --git a/src/services/map-service.js b/src/services/map-service.js
index 128ba6d6c1944b3293d81519f995020af4afcf18..fa21a885caa783817e4ed5f22bea243e5113a398 100644
--- a/src/services/map-service.js
+++ b/src/services/map-service.js
@@ -24,7 +24,7 @@ import Point from 'ol/geom/Point.js';
 import axios from '@/axios-client.js';
 import router from '@/router';
 import store from '@/store';
-import { statusChoices } from '@/utils';
+import { retrieveFeatureProperties } from '@/utils';
 
 let dictLayersToMap = {};
 
@@ -157,11 +157,6 @@ const mapService = {
       console.error(error.message);
     });
     
-    /* const accuracyFeature = new Feature();
-    this.geolocation.on('change:accuracyGeometry', () => {
-      accuracyFeature.setGeometry(this.geolocation.getAccuracyGeometry());
-    }); */
-    
     const positionFeature = new Feature();
     positionFeature.setStyle( geolocationStyle );
     
@@ -179,7 +174,6 @@ const mapService = {
 
     this.geolocationSource = new VectorSource({
       features: [positionFeature],
-      //features: [accuracyFeature, positionFeature],
     });    
     new VectorLayer({
       map: this.map,
@@ -257,7 +251,7 @@ const mapService = {
     document.getElementById('goToFeatureTypeDetail').onclick = goToFeatureTypeDetail;
   },
 
-  onMapClick(event) {
+  async onMapClick (event) {
     //* retrieve features under pointer
     const features = this.map.getFeaturesAtPixel(event.pixel, {
       layerFilter: (l) => l === this.mvtLayer || this.olLayer
@@ -268,7 +262,7 @@ const mapService = {
       const isEdited = router.history.current.name === 'editer-signalement' &&
         router.history.current.params.slug_signal === featureId; //* avoid opening popup on feature currently edited
       if (featureId && !isEdited) {
-        const popupContent = this._createContentPopup(features[0]);
+        const popupContent = await this._createContentPopup(features[0]);
         this.content.innerHTML = popupContent.html;
         this.overlay.setPosition(event.coordinate);
         this.addRouterToPopup({
@@ -488,7 +482,8 @@ const mapService = {
     return { color, opacity };
   },
 
-  addVectorTileLayer: function ({ url, projectId, featureTypes, formFilters = {}, queryParams = {} }) {
+  addVectorTileLayer: function ({ url, project_slug, featureTypes, formFilters = {}, queryParams = {} }) {
+    const projectId = project_slug.split('-')[0];
     const format_cfg = {/*featureClass: Feature*/ };
     const mvt = new MVT(format_cfg);
     const options = {
@@ -506,6 +501,7 @@ const mapService = {
       source: layerSource
     });
     this.featureTypes = featureTypes; // store featureTypes for popups
+    this.projectSlug = project_slug; // store projectSlug for popups
     this.queryParams = queryParams; // store queryParams for popups
 
     this.mvtLayer.setZIndex(30);
@@ -592,7 +588,7 @@ const mapService = {
     }
   },
 
-  addFeatures: function ({ features, filter = {}, featureTypes, addToMap = true, queryParams = {} }) {
+  addFeatures: function ({ features, filter = {}, featureTypes, addToMap = true, project_slug, queryParams = {} }) {
     console.log('addToMap', addToMap);
     const drawSource = new VectorSource();
     let retour;
@@ -619,6 +615,7 @@ const mapService = {
     this.olLayer = olLayer;
     this.drawSource = drawSource;
     this.featureTypes = featureTypes; // store featureTypes for popups
+    this.projectSlug = project_slug; // store projectSlug for popups
     this.queryParams = queryParams; // store queryParams for popup routes
     return drawSource;
   },
@@ -633,18 +630,18 @@ const mapService = {
 
   createCustomFiedsContent(featureType, feature) {
     const { customfield_set } = featureType;
-    if (!customfield_set) return '';
+    // create an html row for a customField
     const rowTemplate = (customfield) => {
       const { label, name } = customfield;
       const value = feature.getProperties()[name];
-      return label && value !== undefined ? `<div class="customField-row">${label}:&nbsp;${value}</div>` : '';
+      return label && value !== undefined ? `<div class="customField-row">${label} : ${value}</div>` : '';
     };
-
+    // generate html for each customField set to be displayed from featureType display config
     let rows = '';
     for (const customField of customfield_set) {
-      rows += rowTemplate(customField);
+      rows += featureType.displayed_fields.includes(customField.name) ? rowTemplate(customField) : '';
     }
-
+    // wrap all rows into customFields container
     return rows.length > 0 ?
       `<div id="customFields">
         <div class="ui divider"></div>
@@ -653,69 +650,30 @@ const mapService = {
       </div>` : '';
   },
 
-  _createContentPopup: function (feature) {
-    const formatDate = (current_datetime) => {
-      let formatted_date = current_datetime.getFullYear() + '-' + ('0' + (current_datetime.getMonth() + 1)).slice(-2) + '-' + ('0' + current_datetime.getDate()).slice(-2) + '&nbsp;' +
-        ('0' + current_datetime.getHours()).slice(-2) + ':' + ('0' + current_datetime.getMinutes()).slice(-2);
-      return formatted_date;
-    };
-    let featureType, status, updated_on, creator, index; // index is used to retrieve feature by query when browsing features
-
-    if (feature.getProperties) {
-      const properties = feature.getProperties();
-      // ! "creator" doesn't exist in geojson, only creator_id is found, but we cannot retrieve the name in frontend's available data
-      ({ status, updated_on, creator, index } = properties); // using parenthesis to allow destructuring object without declaration
-      if (this.featureTypes) {
-        featureType = feature.getProperties().feature_type ||
-          this.featureTypes.find((x) => x.slug.split('-')[0] === '' + feature.getProperties().feature_type_id);
-      }
-    } else { //? TPD: I couldn't find when this code is used, is this still in use ?
-      status = feature.status;
-      if (status) status = status.name;
-      updated_on = feature.updated_on;
-      creator = feature.creator;
-      if (this.featureTypes) {
-        featureType = this.featureTypes.find((x) => x.slug === feature.feature_type.slug);
-      }
-    }
-    if (updated_on && !isNaN(new Date(updated_on))) { //* check if it is already formatted
-      updated_on = formatDate(new Date(updated_on));
-    }
-    if (status) {
-      if (status.label) { //* when the label is already in the feature
-        status = status.label;
-      } else if (this.featureTypes) { //* if not, retrieve the name/label from the list
-        status = statusChoices.find((x) => x.value === status).name;
-      }
-    }
-
-    let author = '';
-    if (creator) {
-      author = creator.full_name
-        ? `<div>
-              Auteur : ${creator.first_name} ${creator.last_name}
-          </div>`
-        : creator.username ? `<div>Auteur: ${creator.username}</div>` : '';
-    }
-
-    const title = feature.getProperties ? feature.getProperties().title : feature.title;
+  _createContentPopup: async function (feature) {
+    const props = await retrieveFeatureProperties(feature, this.featureTypes, this.projectSlug);
+    const { feature_type, index } = props; // index is used to retrieve feature by query when browsing features
+    // generate html for each native fields
+    const statusHtml = `<div>Statut : ${props.status}</div>`;
+    const featureTypeHtml = `<div>Type de signalement : ${feature_type ? '<a id="goToFeatureTypeDetail" class="pointer">' + feature_type.title + '</a>' : 'Type de signalement inconnu'}</div>`;
+    const updatedOnHtml = `<div>Dernière mise à jour : ${props.updated_on}</div>`;
+    const createdOnHtml = `<div>Date de création : ${props.created_on}</div>`;
+    const creatorHtml = props.creator ? `<div>Auteur : ${props.creator}</div>` : '';
+    const lastEditorHtml = props.display_last_editor ? `<div>Dernier éditeur : ${props.display_last_editor}</div>` : '';
+    // wrapping up finale html to fill popup, filtering native fields to display and adding filtered customFields
     const html = `<h4>
-                    <a id="goToFeatureDetail" class="pointer">${title}</a>
+                    <a id="goToFeatureDetail" class="pointer">${feature.getProperties ? feature.getProperties().title : feature.title}</a>
                   </h4>
                   <div class="fields">
-                    <div>
-                      Statut : ${status}
-                    </div>
-                    <div>
-                      Type : ${featureType ? '<a id="goToFeatureTypeDetail" class="pointer">' + featureType.title + '</a>' : 'Type de signalement inconnu'}
-                    </div>
-                    <div>
-                      Dernière&nbsp;mise&nbsp;à&nbsp;jour&nbsp;:&nbsp;${updated_on}
-                    </div>
-                    ${author}
-                    ${this.createCustomFiedsContent(featureType, feature)}
+                    ${feature_type.displayed_fields.includes('status') ? statusHtml : ''}
+                    ${feature_type.displayed_fields.includes('feature_type') ? featureTypeHtml : ''}
+                    ${feature_type.displayed_fields.includes('updated_on') ? updatedOnHtml : ''}
+                    ${feature_type.displayed_fields.includes('created_on') ? createdOnHtml : ''}
+                    ${feature_type.displayed_fields.includes('display_creator') ? creatorHtml : ''}
+                    ${feature_type.displayed_fields.includes('display_last_editor') ? lastEditorHtml : ''}
+                    ${this.createCustomFiedsContent(feature_type, feature)}
                   </div>`;
-    return { html, featureType, index };
+    return { html, feature_type, index };
   },
 
   zoom(zoomlevel) {
diff --git a/src/utils/index.js b/src/utils/index.js
index 53bf9cebd18015f128973c3010e6aefa483ca36e..d8ffcf81d53eac14fe6c731b027e6254b7d1f108 100644
--- a/src/utils/index.js
+++ b/src/utils/index.js
@@ -1,3 +1,5 @@
+import featureAPI from '@/services/feature-api';
+
 export function formatStringDate(stringDate) {
   const date = new Date(stringDate);
   if (date instanceof Date && !isNaN(date.valueOf())) {
@@ -139,6 +141,50 @@ export const featureNativeFields = [
   { name: 'display_last_editor', label: 'Dernier éditeur', field_type: 'Champ GéoContrib' },
 ];
 
+export const formatDate = (current_datetime) => {
+  let formatted_date = current_datetime.getFullYear() + '-' + ('0' + (current_datetime.getMonth() + 1)).slice(-2) + '-' + ('0' + current_datetime.getDate()).slice(-2) + '&nbsp;' +
+    ('0' + current_datetime.getHours()).slice(-2) + ':' + ('0' + current_datetime.getMinutes()).slice(-2);
+  return formatted_date;
+};
+
+export const retrieveFeatureProperties = async (feature, featureTypes, projectSlug) => {
+  const properties = feature.getProperties();
+  let { feature_type, status, updated_on, created_on, creator, display_last_editor, index } = properties;
+  
+  if (creator) { 
+    creator = creator.full_name ? `${creator.first_name} ${creator.last_name}` : creator.username;
+  } else if (properties.feature_id) {
+    //* if *** MVT *** feature, retrieve display_creator and display_last_editor by fetching the feature details from API
+    const fetchedFeature = await featureAPI.getProjectFeature(projectSlug, properties.feature_id);
+    if (fetchedFeature) {
+      creator = fetchedFeature.properties.display_creator;
+      display_last_editor = fetchedFeature.properties.display_last_editor;
+      feature_type = fetchedFeature.properties.feature_type;
+    }
+  }
+  
+  if (featureTypes && feature_type) {
+    feature_type = featureTypes.find((el) => el.slug === feature_type.slug || feature_type);
+  }
+  
+  if (updated_on && !isNaN(new Date(updated_on))) { //* check if date is already formatted
+    updated_on = formatDate(new Date(updated_on));
+  }
+  if (created_on && !isNaN(new Date(created_on))) { //* check if date is already formatted
+    created_on = formatDate(new Date(created_on));
+  }
+  
+  if (status) {
+    if (status.label) { //* when the label is already in the feature
+      status = status.label;
+    } else if (featureTypes) { //* if not, retrieve the name/label from the list
+      status = statusChoices.find((el) => el.value === status).name;
+    }
+  }
+
+  return { feature_type, status, updated_on, created_on, creator, display_last_editor, index };
+};
+
 export function findXformValue(feature, customField) {
   if (!feature) return null;
   if (feature.properties) {
diff --git a/src/views/Feature/FeatureDetail.vue b/src/views/Feature/FeatureDetail.vue
index 991bc5e11c69cbfc82cf830f1848ee455bcd71d8..7a43a9f5aee1762887b6108844f42886df6e8b11 100644
--- a/src/views/Feature/FeatureDetail.vue
+++ b/src/views/Feature/FeatureDetail.vue
@@ -237,6 +237,7 @@ export default {
       isLeaving: false,
       isSavingChanges: false,
       map: null,
+      slug: this.$route.params.slug,
       slugSignal: '',
     };
   },
@@ -293,11 +294,11 @@ export default {
     },
 
     isModerator() {
-      return this.USER_LEVEL_PROJECTS && this.USER_LEVEL_PROJECTS[this.$route.params.slug] === 'Modérateur';
+      return this.USER_LEVEL_PROJECTS && this.USER_LEVEL_PROJECTS[this.slug] === 'Modérateur';
     },
 
     isAdministrator() {
-      return this.USER_LEVEL_PROJECTS && this.USER_LEVEL_PROJECTS[this.$route.params.slug] === 'Administrateur projet';
+      return this.USER_LEVEL_PROJECTS && this.USER_LEVEL_PROJECTS[this.slug] === 'Administrateur projet';
     },
 
     canEditFeature() {
@@ -368,8 +369,8 @@ export default {
       //* Chargements des features et infos projet en cas d'arrivée directe sur la page ou de refresh
       if (!this.project) {
         promises.push(
-          this.GET_PROJECT(this.$route.params.slug),
-          this.GET_PROJECT_INFO(this.$route.params.slug),
+          this.GET_PROJECT(this.slug),
+          this.GET_PROJECT_INFO(this.slug),
         );
       }
       //* changement de requête selon s'il y a un id ou un offset(dans le cas du parcours des signalements filtrés)
@@ -378,7 +379,7 @@ export default {
       } else if (!this.currentFeature || this.currentFeature.id !== this.slugSignal) {
         promises.push(
           this.GET_PROJECT_FEATURE({
-            project_slug: this.$route.params.slug,
+            project_slug: this.slug,
             feature_id: this.slugSignal,
           })
         );
@@ -428,7 +429,7 @@ export default {
       this.$router.push({
         name: 'project_detail',
         params: {
-          slug: this.$route.params.slug,
+          slug: this.slug,
           message,
         },
       });
@@ -451,7 +452,7 @@ export default {
 
     fetchFilteredFeature() { // TODO : if no query for sort, use project default ones
       const queryString = new URLSearchParams({ ...this.$route.query });
-      const url = `${this.$store.state.configuration.VUE_APP_DJANGO_API_BASE}projects/${this.$route.params.slug}/feature-paginated/?limit=1&${queryString}&output=geojson`;
+      const url = `${this.$store.state.configuration.VUE_APP_DJANGO_API_BASE}projects/${this.slug}/feature-paginated/?limit=1&${queryString}&output=geojson`;
       return featureAPI.getPaginatedFeatures(url)
         .then((data) => {
           if (data && data.results && data.results.features && data.results.features[0]) {
@@ -528,8 +529,10 @@ export default {
 
     addFeatureToMap() {
       const featureGroup = mapService.addFeatures({
+        project_slug: this.slug,
         features: [this.currentFeature],
         featureTypes: this.feature_types,
+
         addToMap: true,
       });
       mapService.fitExtent(buffer(featureGroup.getExtent(),200));
diff --git a/src/views/Feature/FeatureEdit.vue b/src/views/Feature/FeatureEdit.vue
index 92b6004a2ae1bdd0f694c28041505002b4b70a39..cc33d39c4e5732c20e75c9c1fafb925200091bed 100644
--- a/src/views/Feature/FeatureEdit.vue
+++ b/src/views/Feature/FeatureEdit.vue
@@ -984,9 +984,10 @@ export default {
               (feat) => feat.id !== currentFeatureId
             );
             mapService.addFeatures({
+              addToMap: true,
+              project_slug: this.project.slug,
               features: allFeaturesExceptCurrent,
               featureTypes: this.feature_types,
-              addToMap: true
             });
             if (this.currentRouteName === 'editer-signalement') {
               editionService.setFeatureToEdit(this.currentFeature);
diff --git a/src/views/Project/FeaturesListAndMap.vue b/src/views/Project/FeaturesListAndMap.vue
index 8bf9e85e87657ace651ff0952826c55b9cd4d0d0..0240d950a5acd6bdd065b3994e2b59b6eeb5c5cd 100644
--- a/src/views/Project/FeaturesListAndMap.vue
+++ b/src/views/Project/FeaturesListAndMap.vue
@@ -347,11 +347,11 @@ export default {
 
       // --------- End sidebar events ----------
       this.$nextTick(() => {
-        const project_id = this.projectSlug.split('-')[0];
+
         const mvtUrl = `${this.API_BASE_URL}features.mvt`;
         mapService.addVectorTileLayer({
           url: mvtUrl,
-          projectId: project_id,
+          project_slug: this.projectSlug,
           featureTypes: this.feature_types,
           formFilters: this.form,
           queryParams: this.queryparams,
diff --git a/src/views/Project/ProjectDetail.vue b/src/views/Project/ProjectDetail.vue
index ccbb87732b5e42f2e4799def93f2c1f67106a205..e30ba3e1bf23a605d7bd1f8cc9057157db769680 100644
--- a/src/views/Project/ProjectDetail.vue
+++ b/src/views/Project/ProjectDetail.vue
@@ -407,11 +407,10 @@ export default {
         }
         await this.INITIATE_MAP({ el: this.$refs.map, layersToLoad });
         this.checkForOfflineFeature();
-        const project_id = this.$route.params.slug.split('-')[0];
         const mvtUrl = `${this.API_BASE_URL}features.mvt`;
         mapService.addVectorTileLayer({
           url: mvtUrl,
-          projectId: project_id,
+          project_slug: this.slug,
           featureTypes: this.feature_types,
           queryParams: {
             ordering: this.project.feature_browsing_default_sort,
@@ -430,13 +429,14 @@ export default {
           .then(() => {
             this.featuresLoading = false;
             mapService.addFeatures({
+              addToMap: true,
+              project_slug: this.slug,
               features: [...this.features, ...featuresOffline],
               featureTypes: this.feature_types,
-              addToMap: true,
               queryParams: {
                 ordering: this.project.feature_browsing_default_sort,
                 filter: this.project.feature_browsing_default_filter,
-              }
+              },
             });
           })
           .catch((err) => {