diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index b5cd343d96bc1009e1d2203399c337a20b907548..0eebfc0f9b8fa4a114826e30b8c3877168bd8a2d 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -44,7 +44,6 @@ build tagged docker image:
   stage: build
   only:
     - tags
-  when: manual
   tags:
     - build
   image:
diff --git a/package.json b/package.json
index 0f0843731dba2192fdb958a3b2d3b750015d43fd..3e59989c8975a3211f294b94343c58eee650a539 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "geocontrib-frontend",
-  "version": "2.1.1",
+  "version": "2.1.2",
   "private": true,
   "scripts": {
     "serve": "npm run init-proxy & npm run init-serve",
diff --git a/src/components/feature/FeatureListTable.vue b/src/components/feature/FeatureListTable.vue
index c7ebb5c23e78db573e2df94005f12a000d1f2a3b..c55b807a95f87ffed6ba8eaca90757c21a92625b 100644
--- a/src/components/feature/FeatureListTable.vue
+++ b/src/components/feature/FeatureListTable.vue
@@ -132,7 +132,7 @@
             {{ feature.properties.updated_on }}
           </td>
           <td class="center" v-if="user">
-            {{ feature.properties.creator.username || " ---- " }}
+            {{ getUserName(feature) }}
           </td>
         </tr>
         <tr v-if="filteredFeatures.length === 0" class="odd">
@@ -296,6 +296,12 @@ export default {
   },
 
   methods: {
+    getUserName(feature){
+      if(!feature.properties.creator) {
+        return " ---- ";
+      }
+      return feature.properties.creator.username || " ---- "
+    },
     getFeatureDisplayName(feature) {
       return feature.properties.title || feature.id;
     },
diff --git a/src/components/feature_type/FeatureTypeCustomForm.vue b/src/components/feature_type/FeatureTypeCustomForm.vue
index 30b0a1e8014f0d788bc73e8d066b63de73315e2f..08b77649d2cd65edd15cbf2ce4d6c09e5c107ead 100644
--- a/src/components/feature_type/FeatureTypeCustomForm.vue
+++ b/src/components/feature_type/FeatureTypeCustomForm.vue
@@ -303,6 +303,12 @@ export default {
     checkCustomForm() {
       this.form.label.errors = [];
       this.form.name.errors = [];
+      this.form.options.errors = [];
+      console.log(
+        this.form.field_type.value,
+        this.form.field_type.value === "list",
+        this.form.options.value.length < 2
+      );
       if (!this.form.label.value) {
         //* vérifier que le label est renseigné
         this.form.label.errors = ["Veuillez compléter ce champ."];
@@ -323,6 +329,13 @@ export default {
           "Les champs personnalisés ne peuvent pas avoir des noms similaires.",
         ];
         return false;
+      } else if (
+        this.form.field_type.value === "list" &&
+        this.form.options.value.length < 2
+      ) {
+        //* s'il s'agit d'un type liste, vérifier que le champ option est bien renseigné
+        this.form.options.errors = ["Veuillez compléter ce champ."];
+        return false;
       }
       return true;
     },
diff --git a/src/main.js b/src/main.js
index 0a69972e540c108429f5a9c6939c30e66010786a..4a1f3128cd2ba8ca6a755be82f949b99d29851ad 100644
--- a/src/main.js
+++ b/src/main.js
@@ -10,26 +10,49 @@ import 'leaflet-draw/dist/leaflet.draw.css';
 import '@/assets/resources/leaflet-control-geocoder-1.13.0/Control.Geocoder.css';
 Vue.config.productionTip = false
 
+// gestion mise à jour du serviceWorker et du precache
+var refreshing=false;
+navigator.serviceWorker.addEventListener('controllerchange', () => {
+  // We'll also need to add 'refreshing' to our data originally set to false.
+  if (refreshing) return
+  refreshing = true
+  // Here the actual reload of the page occurs
+  window.location.reload()
+})
+
+
+let onConfigLoaded = function(config){
+  store.commit("SET_CONFIG", config);
+  window.proxy_url=config.VUE_APP_DJANGO_API_BASE+"proxy/";
+  axios.all([store.dispatch("USER_INFO"),
+    store.dispatch("GET_ALL_PROJECTS"),
+    store.dispatch("GET_STATIC_PAGES"),
+    store.dispatch("GET_USER_LEVEL_PROJECTS"),
+    store.dispatch("map/GET_AVAILABLE_LAYERS"),
+    store.dispatch("GET_USER_LEVEL_PERMISSIONS"),
+  ]).then(axios.spread(function () {
+    new Vue({
+      router,
+      store,
+      render: h => h(App)
+    }).$mount('#app')
+  }));
+
+}
 
 axios.get("./config/config.json")
+  .catch((error)=>{
+    console.log(error);
+    console.log("try to get From Localstorage");
+    let conf=localStorage.getItem("geontrib_conf");
+    if(conf){
+      onConfigLoaded(JSON.parse(conf))
+    }
+  })
   .then((response) => {
     if (response && response.status === 200) {
-      store.commit("SET_CONFIG", response.data);
-      window.proxy_url = response.data.VUE_APP_DJANGO_API_BASE + "proxy/"
-      axios.all([
-        store.dispatch("USER_INFO"),
-        store.dispatch("GET_ALL_PROJECTS"),
-        store.dispatch("GET_STATIC_PAGES"),
-        store.dispatch("GET_USER_LEVEL_PROJECTS"),
-        store.dispatch("map/GET_AVAILABLE_LAYERS"),
-        store.dispatch("GET_USER_LEVEL_PERMISSIONS"),
-      ]).then(axios.spread(function () {
-        new Vue({
-          router,
-          store,
-          render: h => h(App)
-        }).$mount('#app')
-      }))
+      localStorage.setItem("geontrib_conf",JSON.stringify(response.data));
+      onConfigLoaded(response.data)
     }
   })
   .catch((error) => {
diff --git a/src/registerServiceWorker.js b/src/registerServiceWorker.js
index 76cede074d8a8393586f6567de3020e2e506591d..0fea28955951af66f5cce9aa2df7e57716b5b329 100644
--- a/src/registerServiceWorker.js
+++ b/src/registerServiceWorker.js
@@ -10,8 +10,14 @@ if (process.env.NODE_ENV === 'production') {
         'For more details, visit https://goo.gl/AFskqB'
       )
     },
-    registered () {
-      console.log('Service worker has been registered.')
+    registered (registration) {
+      //console.log('Service worker has been registered.')
+      console.log(
+        'Service worker has been registered and now polling for updates.'
+      )
+      setInterval(() => {
+        registration.update()
+      }, 10000) // every 10 seconds
     },
     cached () {
       console.log('Content has been cached for offline use.')
@@ -19,8 +25,14 @@ if (process.env.NODE_ENV === 'production') {
     updatefound () {
       console.log('New content is downloading.')
     },
-    updated () {
-      console.log('New content is available; please refresh.')
+    updated (registration) {
+      alert('Une nouvelle version de l\'application est disponible, l\'application va se recharger');
+      console.log('New content is available; please refresh.');
+      //
+      if (!registration || !registration.waiting) return
+      // Send message to SW to skip the waiting and activate the new SW
+      registration.waiting.postMessage({ type: 'SKIP_WAITING' })
+      //window.location.reload(true);
     },
     offline () {
       console.log('No internet connection found. App is running in offline mode.')
diff --git a/src/router/index.js b/src/router/index.js
index 035bafb0d27e113d77fab3d5fc207db3050e7356..f0eb56d71e8a8442ffd6d914291a1114e2eb3281 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -108,6 +108,11 @@ const routes = [
     name: 'details-signalement',
     component: () => import('../views/feature/Feature_detail.vue')
   },
+  {
+    path: '/projet/:slug/type-signalement/:slug_type_signal/offline',
+    name: 'offline-signalement',
+    component: () => import('../views/feature/Feature_offline.vue')
+  },
   {
     path: '/projet/:slug/type-signalement/:slug_type_signal/signalement/:slug_signal/editer/',
     name: 'editer-signalement',
diff --git a/src/service-worker.js b/src/service-worker.js
new file mode 100644
index 0000000000000000000000000000000000000000..7497fb0ca7f6f2d73661d696f8fa189c69640695
--- /dev/null
+++ b/src/service-worker.js
@@ -0,0 +1,64 @@
+// custom service-worker.js
+if (workbox) {
+    // adjust log level for displaying workbox logs
+    //workbox.core.setLogLevel(workbox.core.LOG_LEVELS.debug)
+
+    // apply precaching. In the built version, the precacheManifest will
+    // be imported using importScripts (as is workbox itself) and we can 
+    // precache this. This is all we need for precaching
+    workbox.precaching.precacheAndRoute(self.__precacheManifest);
+
+    //workbox.core.skipWaiting();
+
+    // Make sure to return a specific response for all navigation requests.
+    // Since we have a SPA here, this should be index.html always.
+    // https://stackoverflow.com/questions/49963982/vue-router-history-mode-with-pwa-in-offline-mode
+    workbox.routing.registerNavigationRoute('/geocontrib/index.html')
+
+    workbox.routing.registerRoute(
+        new RegExp('.*/config/config.json'),
+        new workbox.strategies.StaleWhileRevalidate({
+            cacheName: 'config',
+        })
+    )
+
+    workbox.routing.registerRoute(
+        new RegExp('.*/api/.*'),
+        new workbox.strategies.NetworkFirst({
+            cacheName: 'api',
+        })
+    )
+    workbox.routing.registerRoute(
+        /^https:\/\/c\.tile\.openstreetmap\.fr/,
+        new workbox.strategies.CacheFirst({
+            cacheName: 'osm',
+            plugins: [
+                new workbox.cacheableResponse.Plugin({
+                    statuses: [0, 200],
+                }),
+                new workbox.expiration.Plugin({
+                    maxAgeSeconds: 60 * 60 * 24 * 365,
+                    // maxEntries: 30, pour limiter le nombre d'entrée dans le cache
+                }),
+            ],
+        })
+    )
+
+}
+
+// This code listens for the user's confirmation to update the app.
+self.addEventListener('message', (e) => {
+    if (!e.data) {
+        return;
+    }
+    //console.log(e.data);
+    switch (e.data.type) {
+        case 'SKIP_WAITING':
+            self.skipWaiting();
+            break;
+        default:
+            // NOOP
+            break;
+    }
+})
+
diff --git a/src/store/modules/feature.js b/src/store/modules/feature.js
index 9b629c72ca3f301918d20e238778fe29739d02e9..72b383a7be2634c741475ed4aa65250095467371 100644
--- a/src/store/modules/feature.js
+++ b/src/store/modules/feature.js
@@ -179,6 +179,33 @@ const feature = {
           })
           .catch((error) => {
             commit("DISCARD_LOADER", null, { root: true })
+            if(error.message=="Network Error" ||window.navigator.onLine==false){
+              let arraysOffline=[];
+              let localStorageArray=localStorage.getItem("geocontrib_offline");
+              if(localStorageArray){
+                arraysOffline=JSON.parse(localStorageArray);
+              }
+              let updateMsg={
+                project:rootState.project_slug,
+                type:'put',
+                featureId:state.form.feature_id,
+                geojson:geojson
+              };
+              arraysOffline.push(updateMsg);
+              localStorage.setItem("geocontrib_offline",JSON.stringify(arraysOffline));
+              router.push({
+                name: "offline-signalement",
+                params: {
+                  slug_type_signal: rootState.feature_type.current_feature_type_slug
+                },
+              });
+
+            }
+            else{
+              console.log(error)
+              throw error;
+            }
+            
             throw error;
           });
       } else {
@@ -195,7 +222,32 @@ const feature = {
           })
           .catch((error) => {
             commit("DISCARD_LOADER", null, { root: true })
-            throw error;
+            if(error.message=="Network Error" ||window.navigator.onLine==false){
+              let arraysOffline=[];
+              let localStorageArray=localStorage.getItem("geocontrib_offline");
+              if(localStorageArray){
+                arraysOffline=JSON.parse(localStorageArray);
+              }
+              let updateMsg={
+                project:rootState.project_slug,
+                type:'post',
+                geojson:geojson
+              };
+              arraysOffline.push(updateMsg);
+              localStorage.setItem("geocontrib_offline",JSON.stringify(arraysOffline));
+              router.push({
+                name: "offline-signalement",
+                params: {
+                  slug_type_signal: rootState.feature_type.current_feature_type_slug
+                },
+              });
+
+            }
+            else{
+              console.log(error)
+              throw error;
+            }
+            
           });
       }
     },
diff --git a/src/views/Index.vue b/src/views/Index.vue
index ca7e4fc7cbf83ef91638e4fdfed935cc7cf5c875..e199657757733fb9d0874e0c72e2a47fd9f04d8b 100644
--- a/src/views/Index.vue
+++ b/src/views/Index.vue
@@ -15,14 +15,14 @@
     <h4 id="les_projets" class="ui horizontal divider header">PROJETS</h4>
     <div class="flex">
       <router-link
-        v-if="user && user.can_create_project"
+        v-if="user && user.can_create_project && isOffline()!=true"
         :to="{ name: 'project_create', params: { action: 'create' } }"
         class="ui green basic button"
       >
         <i class="plus icon"></i> Créer un nouveau projet
       </router-link>
       <router-link
-        v-if="user && user.can_create_project"
+        v-if="user && user.can_create_project && isOffline()!=true"
         :to="{
           name: 'project_type_list',
         }"
@@ -124,6 +124,9 @@ export default {
   },
 
   methods: {
+    isOffline(){
+      return navigator.onLine==false;
+    },
     refreshId() {
       //* change path of thumbnail to update image
       return "?ver=" + Math.random();
diff --git a/src/views/feature/Feature_edit.vue b/src/views/feature/Feature_edit.vue
index 49c6e111cf4ca440b819e290c92e863b9515470b..1dc8b37cb83ade39e4b14299b837b630763b0552 100644
--- a/src/views/feature/Feature_edit.vue
+++ b/src/views/feature/Feature_edit.vue
@@ -4,7 +4,7 @@
       type="application/javascript"
       :src="
         baseUrl +
-        '/resources/leaflet-control-geocoder-1.13.0/Control.Geocoder.js'
+        'resources/leaflet-control-geocoder-1.13.0/Control.Geocoder.js'
       "
     ></script>
     <div class="fourteen wide column">
@@ -72,7 +72,7 @@
 
           <!-- Import GeoImage -->
           <div v-frag v-if="feature_type && feature_type.geom_type === 'point'">
-            <p>
+            <p v-if="isOffline()!=true">
               <button
                 @click="toggleGeoRefModal"
                 id="add-geo-image"
@@ -207,45 +207,48 @@
         </div>
 
         <!-- Pièces jointes -->
-        <div class="ui horizontal divider">PIÈCES JOINTES</div>
-        <div id="formsets-attachment">
-          <FeatureAttachmentForm
-            v-for="form in attachmentFormset"
-            :key="form.dataKey"
-            :attachmentForm="form"
-            ref="attachementForm"
-          />
-        </div>
+        <div v-if="isOffline()!=true">
+          <div class="ui horizontal divider">PIÈCES JOINTES</div>
+          <div v-if="isOffline()!=true" id="formsets-attachment">
+            <FeatureAttachmentForm
+              v-for="form in attachmentFormset"
+              :key="form.dataKey"
+              :attachmentForm="form"
+              ref="attachementForm"
+            />
+          </div>
 
-        <button
-          @click="add_attachement_formset"
-          id="add-attachment"
-          type="button"
-          class="ui compact basic button button-hover-green"
-        >
-          <i class="ui plus icon"></i>Ajouter une pièce jointe
-        </button>
+          <button
+            @click="add_attachement_formset"
+            id="add-attachment"
+            type="button"
+            class="ui compact basic button button-hover-green"
+          >
+            <i class="ui plus icon"></i>Ajouter une pièce jointe
+          </button>
+        </div>
 
         <!-- Signalements liés -->
-        <div class="ui horizontal divider">SIGNALEMENTS LIÉS</div>
-        <div id="formsets-link">
-          <FeatureLinkedForm
-            v-for="form in linkedFormset"
-            :key="form.dataKey"
-            :linkedForm="form"
-            :features="features"
-            ref="linkedForm"
-          />
+        <div v-if="isOffline()!=true">
+          <div class="ui horizontal divider">SIGNALEMENTS LIÉS</div>
+          <div id="formsets-link">
+            <FeatureLinkedForm
+              v-for="form in linkedFormset"
+              :key="form.dataKey"
+              :linkedForm="form"
+              :features="features"
+              ref="linkedForm"
+            />
+          </div>
+          <button
+            @click="add_linked_formset"
+            id="add-link"
+            type="button"
+            class="ui compact basic button button-hover-green"
+          >
+            <i class="ui plus icon"></i>Ajouter une liaison
+          </button>
         </div>
-        <button
-          @click="add_linked_formset"
-          id="add-link"
-          type="button"
-          class="ui compact basic button button-hover-green"
-        >
-          <i class="ui plus icon"></i>Ajouter une liaison
-        </button>
-
         <div class="ui divider"></div>
 
         <button @click="postForm" type="button" class="ui teal icon button">
@@ -440,6 +443,9 @@ export default {
   },
 
   methods: {
+    isOffline(){
+      return navigator.onLine==false;
+    },
     initForm() {
       if (this.currentRouteName === "editer-signalement") {
         for (let key in this.feature) {
diff --git a/src/views/feature/Feature_list.vue b/src/views/feature/Feature_list.vue
index e3906d9f6020911433cbd6fcf232f1cd49506ce5..667e974de35c926248f704fa1a6c94f85bf44362 100644
--- a/src/views/feature/Feature_list.vue
+++ b/src/views/feature/Feature_list.vue
@@ -4,7 +4,7 @@
       type="application/javascript"
       :src="
         baseUrl +
-        '/resources/leaflet-control-geocoder-1.13.0/Control.Geocoder.js'
+        'resources/leaflet-control-geocoder-1.13.0/Control.Geocoder.js'
       "
     ></script>
     <div id="feature-list-container" class="ui grid mobile-column">
diff --git a/src/views/feature/Feature_offline.vue b/src/views/feature/Feature_offline.vue
new file mode 100644
index 0000000000000000000000000000000000000000..fb8a89bd8e14f663924e90e294a8a43dc60956dd
--- /dev/null
+++ b/src/views/feature/Feature_offline.vue
@@ -0,0 +1,41 @@
+<template>
+  <div v-frag>
+    Erreur Réseau lors de l'envoi du signalement. Votre signalement devra être envoyé au serveur quand vous aurez de nouveau accès à internet.
+    Veuillez à ce moment là cliquer sur Envoyer sur la page principale du projet 
+    <router-link
+            :to="{
+              name: 'project_detail',
+              params: { slug: $route.params.slug },
+            }"
+            class="header"
+            >Retour au projet</router-link
+          >
+  </div>
+</template>
+
+<script>
+import frag from "vue-frag";
+
+export default {
+  name: "Feature_offline",
+
+  directives: {
+    frag,
+  },
+
+  data() {
+    return {
+    };
+  },
+
+  computed: {
+  },
+  methods: {
+    
+  }
+};
+</script>
+
+<style>
+
+</style>
\ No newline at end of file
diff --git a/src/views/project/Project_detail.vue b/src/views/project/Project_detail.vue
index 80c6ff8705d1719ca1709e3e8656b731ebf86620..d4a8636f340ea9e0a3189a21f33be644403afac6 100644
--- a/src/views/project/Project_detail.vue
+++ b/src/views/project/Project_detail.vue
@@ -52,9 +52,19 @@
           <h1 class="ui header">
             <div class="content">
               {{ project.title }}
+              <div v-if="arraysOffline.length>0">{{arraysOffline.length}} modifications en attente
+                <button
+                :disabled="isOffline()"
+                @click="sendOfflineFeatures()"
+                class="ui fluid teal icon button"
+              >
+                <i class="upload icon"></i> Envoyer au serveur
+              </button>
+
+              </div>
               <div class="ui icon right floated compact buttons">
                 <a
-                  v-if="user && permissions && permissions.can_view_project"
+                  v-if="user && permissions && permissions.can_view_project && isOffline()!=true"
                   id="subscribe-button"
                   class="ui button button-hover-green"
                   data-tooltip="S'abonner au projet"
@@ -65,7 +75,7 @@
                   <i class="inverted grey envelope icon"></i>
                 </a>
                 <router-link
-                  v-if="permissions && permissions.can_update_project"
+                  v-if="permissions && permissions.can_update_project && isOffline()!=true"
                   :to="{ name: 'project_edit', params: { slug: project.slug } }"
                   class="ui button button-hover-orange"
                   data-tooltip="Modifier le projet"
@@ -156,7 +166,7 @@
                   v-if="
                     project &&
                     permissions &&
-                    permissions.can_create_feature_type
+                    permissions.can_create_feature_type && isOffline()!=true
                   "
                   class="
                     ui
@@ -182,7 +192,7 @@
                     project &&
                     type.is_editable &&
                     permissions &&
-                    permissions.can_create_feature_type
+                    permissions.can_create_feature_type && isOffline()!=true
                   "
                   class="
                     ui
@@ -208,7 +218,7 @@
 
           <div class="nouveau-type-signalement">
             <router-link
-              v-if="permissions && permissions.can_update_project"
+              v-if="permissions && permissions.can_update_project && isOffline()!=true"
               :to="{
                 name: 'ajouter-type-signalement',
                 params: { slug: project.slug },
@@ -220,7 +230,7 @@
           </div>
           <div class="nouveau-type-signalement">
             <a
-              v-if="permissions && permissions.can_update_project"
+              v-if="permissions && permissions.can_update_project && isOffline()!=true"
               class="
                 ui
                 compact
@@ -493,6 +503,7 @@ export default {
   data() {
     return {
       infoMessage: "",
+      arraysOffline: [],
       geojsonImport: [],
       fileToImport: { name: "", size: 0 },
       slug: this.$route.params.slug,
@@ -520,7 +531,68 @@ export default {
     refreshId() {
       return "?ver=" + Math.random();
     },
+    isOffline(){
+      return navigator.onLine==false;
+    },
+    checkForOfflineFeature(){
+      let arraysOffline=[];
+      let localStorageArray=localStorage.getItem("geocontrib_offline");
+      if(localStorageArray){
+        arraysOffline=JSON.parse(localStorageArray);
+        this.arraysOffline=arraysOffline.filter(x=>x.project==this.project.slug);
+      }
+    },
+    sendOfflineFeatures(){
+      var promises = [];
+      this.arraysOffline.forEach((feature, index, object)=>{
+        console.log(feature);
+        if(feature.type=='post') {
+          promises.push(
+          axios
+          .post(`${this.$store.state.configuration.VUE_APP_DJANGO_API_BASE}features/`, feature.geojson)
+          .then((response) => {
+            console.log(response)
+            if (response.status === 201 && response.data) {
+              object.splice(index, 1);
+            }
+          })
+          .catch((error) => {
+            console.log(error);
+          }));
+        }
+        else if(feature.type=='put') {
+          promises.push(
+          axios
+          .put(`${this.$store.state.configuration.VUE_APP_DJANGO_API_BASE}features/${feature.featureId}`, feature.geojson)
+          .then((response) => {
+            console.log(response)
+            if (response.status === 200 && response.data) {
+              object.splice(index, 1);
+            }
+          })
+          .catch((error) => {
+            console.log(error);
+          }));
+        }
+      });
+      Promise.all(promises).then(() => {
+          this.updateLocalStorage();
+          window.location.reload();
+      }
 
+      );
+      
+    },
+    updateLocalStorage(){
+      let arraysOffline=[];
+      let localStorageArray=localStorage.getItem("geocontrib_offline");
+      if(localStorageArray){
+        arraysOffline=JSON.parse(localStorageArray);
+      }
+      let arraysOfflineOtherProject = arraysOffline.filter(x=>x.project!=this.project.slug);
+      arraysOffline=arraysOfflineOtherProject.concat(this.arraysOffline);
+      localStorage.setItem("geocontrib_offline",JSON.stringify(arraysOffline));
+    },
     toNewFeatureType() {
       this.$router.push({
         name: "ajouter-type-signalement",
@@ -585,10 +657,14 @@ export default {
     if (this.project && this.permissions.can_view_project) {
       this.$store.dispatch("map/INITIATE_MAP");
       const url = `${this.$store.state.configuration.VUE_APP_DJANGO_API_BASE}projects/${this.$route.params.slug}/feature/?output=geojson`;
+      let self = this;
+      this.checkForOfflineFeature();
       axios
         .get(url)
         .then((response) => {
-          const features = response.data.features;
+          let features = response.data.features;
+          self.arraysOffline.forEach(x=>x.geojson.properties.color="red");
+          features=response.data.features.concat(self.arraysOffline.map(x=>x.geojson));
           const featureGroup = mapUtil.addFeatures(features);
           if (featureGroup && featureGroup.getLayers().length > 0) {
             mapUtil
@@ -602,6 +678,8 @@ export default {
         .catch((error) => {
           throw error;
         });
+      
+
     }
 
     if (this.message) {
diff --git a/vue.config.js b/vue.config.js
index 8e550623b56b7de8f5580c7b8d6bbe6144f5310d..777fbbbaf0383828440b5391b142cb44add79982 100644
--- a/vue.config.js
+++ b/vue.config.js
@@ -3,15 +3,36 @@ const fs = require('fs')
 const packageJson = fs.readFileSync('./package.json')
 const version = JSON.parse(packageJson).version || 0
 module.exports = {
-  publicPath: '/geocontrib/',
-  configureWebpack: {
-    plugins: [
-      new webpack.DefinePlugin({
-        'process.env': {
-          PACKAGE_VERSION: '"' + version + '"'
+    publicPath: '/geocontrib/',
+    devServer: {
+        proxy: {
+            '^/api': {
+                target: 'https://geocontrib.dev.neogeo.fr/api',
+                ws: true,
+                changeOrigin: true
+            }
         }
-      })
-    ]
-  },
-  // the rest of your original module.exports code goes here
+    },
+    pwa: {
+        workboxPluginMode: 'InjectManifest',
+        workboxOptions: {
+            swSrc: 'src/service-worker.js',
+            exclude: [
+                /\.map$/, 
+                /config\/config.*\.json$/,
+                /manifest\.json$/ 
+            ],
+        },
+        themeColor: '#1da025'
+      },
+    configureWebpack: {
+        plugins: [
+            new webpack.DefinePlugin({
+                'process.env': {
+                    PACKAGE_VERSION: '"' + version + '"'
+                }
+            })
+        ]
+    },
+// the rest of your original module.exports code goes here
 }