diff --git a/assets/img/loader.gif b/assets/img/loader.gif
index 266f7b4ad48a6b375fa54c8957a2c7b2945c14e9..c6f22e215d4f188e56073c5148fd48bd124174f2 100644
Binary files a/assets/img/loader.gif and b/assets/img/loader.gif differ
diff --git a/graphql/queries.js b/graphql/queries.js
new file mode 100644
index 0000000000000000000000000000000000000000..1a99cbb18a3eef4edd9b8fa8bc6a2004e6683819
--- /dev/null
+++ b/graphql/queries.js
@@ -0,0 +1,214 @@
+import gql from "graphql-tag"
+
+// Pour la page index
+export const LAST_EVENTS = gql`query LastEvents($start: Int64, $end: Int64) {
+    membersCount(start: $start, end: $end) {
+        idList {
+            member : id {
+                pubkey
+                uid
+                status
+                hash
+                limitDate
+                received_certifications {
+                limit
+                }
+            }
+            inOut
+        },
+        block {
+            number
+        }
+    }
+} `
+
+// Pour la page previsions/index
+export const PREVISIONS = gql`query {
+    now {
+        number
+        bct
+    }
+    parameter(name: sigQty) {
+        sigQty:value
+    }
+    wwFile(full: true) {
+        certifs_dossiers {
+            ... on MarkedDatedCertification {
+                datedCertification {
+                    date
+                    certification {
+                        from {
+                            uid
+                        }
+                        to {
+                            uid
+                        }
+                        expires_on
+                    }
+                }
+            }
+            ... on MarkedDossier {
+                dossier {
+                    main_certifs
+                    newcomer {
+                        uid
+                        lastApplication {
+                            lastAppDate: bct
+                        }
+                        distance: distanceE {
+                            value {
+                                ratio
+                            }
+                            dist_ok
+                        }
+                    }
+                    date
+                    minDate
+                    expires_on:limit
+                    certifications {
+                        date
+                        certification {
+                            from {
+                                uid
+                                quality {
+                                    ratio
+                                }
+                            }
+                            expires_on
+                        }
+                    }
+                }
+            }
+        }
+    }
+} `
+
+// Pour la page previsions/_hash
+export const PREVISION = gql`query Search($hash: Hash!) {
+    idFromHash(hash: $hash) {
+        ...memberAttributes
+        pubkey
+        isLeaving
+        sentry
+        minDate
+        minDatePassed
+        membership_pending
+        limitDate
+        distance {
+            value {
+                ratio
+            }
+            dist_ok
+        }
+        received_certifications {
+            certifications {
+                from {
+                    ...memberAttributes
+                }
+                expires_on
+            }
+        }
+        sent_certifications {
+            to {
+                ...memberAttributes
+            }
+            expires_on
+        }
+    }
+}
+fragment memberAttributes on Identity {
+    uid
+    hash
+    status
+    quality {
+        ratio
+    }
+    received_certifications {
+        limit
+    }
+}`
+
+// Pour la page previsions/newcomers
+export const NEWCOMERS = gql`query {
+    wwResult {
+        permutations_nb
+        dossiers_nb
+        certifs_nb
+        forecastsByNames {
+            member : id {
+                pubkey
+                uid
+                status
+                hash
+                limitDate
+                received_certifications {
+                    limit
+                }
+            }
+            date
+            after
+            proba
+        }
+    }
+} `
+
+// Pour la page membres/index
+export const SEARCH_MEMBERS = gql`query Search($hint: String) {
+    idSearch(with: {hint: $hint}) {
+        ids {
+            pubkey
+            uid
+            status
+            hash
+            limitDate
+            received_certifications {
+                limit
+            }
+        }
+    }
+} `
+
+// Pour la page membres/_hash
+export const SEARCH_MEMBER = gql`query Search($hash: Hash!) {
+    idFromHash(hash: $hash) {
+        ...memberAttributes
+        pubkey
+        isLeaving
+        sentry
+        minDate
+        minDatePassed
+        membership_pending
+        limitDate
+        distance {
+            value {
+                ratio
+            }
+            dist_ok
+        }
+        received_certifications {
+            certifications {
+            from {
+                ...memberAttributes
+            }
+            expires_on
+            }
+        }
+        sent_certifications {
+            to {
+                ...memberAttributes
+            }
+            expires_on
+        }
+    }
+}
+fragment memberAttributes on Identity {
+    uid
+    hash
+    status
+    quality {
+        ratio
+    }
+    received_certifications {
+        limit
+    }
+}`
\ No newline at end of file
diff --git a/pages/index.vue b/pages/index.vue
index bd6d156321095a867067fb41dbf4aec5d07d3274..5169785c1c7af274bfabdfa2a93e14fefdd8e83f 100644
--- a/pages/index.vue
+++ b/pages/index.vue
@@ -2,69 +2,46 @@
 <main class="container">
   <h2 class="text-center mb-5 font-weight-light">Entrées et sorties de la toile de confiance des 2 derniers jours</h2>
   <NavigationLoader :isLoading="$apollo.queries.newMembers.loading" />
-  <div class="result" :class={hidden:$apollo.queries.newMembers.loading}>
-    <div class="row text-center" v-if="!$apollo.queries.newMembers.loading && newMembers">
-      <div class="col-lg-6">
-        <h2 class="h4 text-success">Bienvenue à</h2>
-        <MemberList :members="newMembers['entrees']" :displayPubkey="false" :displayHead="false" />
-      </div>
-      <div class="col-lg-6">
-        <h2 class="h4 text-danger">Au revoir à</h2>
-        <MemberList :members="newMembers['sorties']" :displayPubkey="false" :displayHead="false" />
+  <transition name="fade">
+    <div class="alert alert-danger" v-if="error">{{ error }}</div>
+    <div class="result" v-if="newMembers">
+      <div class="row text-center">
+        <div class="col-lg-6">
+          <h2 class="h4 text-success">Bienvenue à</h2>
+          <MemberList :members="newMembers['entrees']" :displayPubkey="false" :displayHead="false" />
+        </div>
+        <div class="col-lg-6">
+          <h2 class="h4 text-danger">Au revoir à</h2>
+          <MemberList :members="newMembers['sorties']" :displayPubkey="false" :displayHead="false" />
+        </div>
       </div>
     </div>
-  </div>
-
+  </transition>
 </main>
 </template>
 
 <script>
-import gql from 'graphql-tag'
+import {LAST_EVENTS} from '@/graphql/queries.js'
 
 const today = Math.round(Date.now() /1000)
 
 export default {
   data() {
-    // Variables locales
     return {
-      // Fil d'ariane
       breadcrumb: [
         {
           text: 'Accueil',
           to: '/'
         }
-      ]
+      ],
+      error: null
     }
-  },
-  // Fonctions locales
-  methods: {
-
   },
   apollo: {
     newMembers : {
-      query: gql`query LastEvents($start: Int64, $end: Int64) {
-        membersCount(start: $start, end: $end) {
-          idList {
-            member : id {
-              pubkey
-              uid
-              status
-              hash
-              limitDate
-              received_certifications {
-                limit
-              }
-            }
-            inOut
-          },
-          block {
-            number
-          }
-        }
-      } `,
-      variables(){return {start:today-86400*2,end:today}},
+      query: LAST_EVENTS,
+      variables() {return {start:today-86400*2,end:today}},
       update (data) {
-        console.log(data)
         let result = {'entrees':[],'sorties':[]}
 
         for (let i = 0; i < data.membersCount.length; i++) {
@@ -87,7 +64,8 @@ export default {
         }
         
         return result
-      }
+      },
+      error (err) {this.error = err.message}
     }
   },
   mounted () {
diff --git a/pages/membres/_hash.vue b/pages/membres/_hash.vue
index b1336be3263a2644829b074206ce9af317691b62..dcfbd52fa735a1771c59cd9d213ef8021aed788e 100644
--- a/pages/membres/_hash.vue
+++ b/pages/membres/_hash.vue
@@ -2,6 +2,7 @@
   <main class="content container">
     <NavigationLoader :isLoading="$apollo.queries.idFromHash.loading" />
     <transition name="fade">
+      <div class="alert alert-danger" v-if="error">{{ error }}</div>
       <div v-if="idFromHash">
         <div class="row">
           <div class="col-md-10 col-lg-8 col-xl-6 mx-auto mt-3">
@@ -26,7 +27,7 @@
 </template>
 
 <script>
-import gql from "graphql-tag"
+import {SEARCH_MEMBER} from "@/graphql/queries"
 
 export default {
   data() {
@@ -45,64 +46,17 @@ export default {
           text: '',
           active: true
         }
-      ]
+      ],
+      error: null
     };
   },
   // Fonctions locales
   methods: {},
   apollo: {
     idFromHash: {
-      query: gql`
-        query Search($hash: Hash!) {
-          idFromHash(hash: $hash) {
-            ...memberAttributes
-            pubkey
-            isLeaving
-            sentry
-            minDate
-            minDatePassed
-            membership_pending
-            limitDate
-            distance {
-              value {
-                ratio
-              }
-              dist_ok
-            }
-            received_certifications {
-              certifications {
-                from {
-                  ...memberAttributes
-                }
-                expires_on
-              }
-            }
-            sent_certifications {
-              to {
-                ...memberAttributes
-              }
-              expires_on
-            }
-          }
-        }
-        fragment memberAttributes on Identity {
-          uid
-          hash
-          status
-          quality {
-            ratio
-          }
-          received_certifications {
-            limit
-          }
-        }
-      `,
-      variables() {
-        return { hash: this.$route.params.hash };
-      },
-      skip() {
-        return false;
-      },
+      query: SEARCH_MEMBER,
+      variables() {return { hash: this.$route.params.hash }},
+      error (err) {this.error = err.message}
     },
   },
   computed: {
diff --git a/pages/membres/index.vue b/pages/membres/index.vue
index f12720d41387d794ee7d63c5729a9dcc81029b3c..c4fbd8ff05bc6eb2219450b957f42fe118c9e69a 100644
--- a/pages/membres/index.vue
+++ b/pages/membres/index.vue
@@ -10,7 +10,8 @@
   </div>
   <NavigationLoader :isLoading="$apollo.queries.idSearch.loading" />
   <transition name="fade">
-    <div class="row" v-if="idSearch && !$apollo.queries.idSearch.loading && param.length > 2">
+    <div class="alert alert-danger" v-if="error">{{ error }}</div>
+    <div class="row" v-if="idSearch && param.length>2">
       <div class="col-8 m-auto">
         <MemberList :members="idSearch.ids"/>
       </div>
@@ -20,13 +21,11 @@
 </template>
 
 <script>
-import gql from 'graphql-tag'
+import {SEARCH_MEMBERS} from '@/graphql/queries'
 
 export default {
   data() {
-    // Variables locales
     return {
-      // Fil d'ariane
       breadcrumb: [
         {
           text: 'Accueil',
@@ -37,8 +36,8 @@ export default {
           active: true
         }
       ],
-      // Requête graphQL
       param: '',
+      error: null
     }
   },
   // Fonctions locales
@@ -49,23 +48,10 @@ export default {
   },
   apollo: {
     idSearch : {
-      query: gql`
-      query Search($hint: String) {
-        idSearch(with: {hint: $hint}) {
-          ids {
-            pubkey
-            uid
-            status
-            hash
-            limitDate
-            received_certifications {
-              limit
-            }
-          }
-        }
-      } `,
-      variables(){return {hint:this.param}},
-      skip() {return this.param.length < 3}
+      query: SEARCH_MEMBERS,
+      variables() {return {hint:this.param}},
+      skip() {return this.param.length < 3},
+      error (err) {this.error = err.message}
     } 
   },
   mounted () {
diff --git a/pages/previsions/_hash.vue b/pages/previsions/_hash.vue
index 352623476a0b6be05f8b86b098c67002192c4568..4cfc380c1782317d9761d24467503858118dd096 100644
--- a/pages/previsions/_hash.vue
+++ b/pages/previsions/_hash.vue
@@ -2,7 +2,8 @@
   <main class="content container">
     <NavigationLoader :isLoading="$apollo.queries.idFromHash.loading" />
     <transition name="fade">
-      <div v-if="!$apollo.queries.idFromHash.loading">
+      <div class="alert alert-danger" v-if="error">{{ error }}</div>
+      <div v-if="idFromHash">
         <div class="row">
           <div class="col-md-10 col-lg-8 col-xl-6 mx-auto mt-3">
             <h2 class="text-center mb-5 font-weight-light">Prévisions <small><span class="badge badge-secondary">{{ idFromHash.uid }}</span></small></h2>
@@ -15,7 +16,7 @@
 </template>
 
 <script>
-import gql from "graphql-tag"
+import {PREVISION} from "@/graphql/queries"
 
 export default {
   data() {
@@ -34,64 +35,17 @@ export default {
           text: '',
           active: true
         }
-      ]
+      ],
+      error: null
     };
   },
   // Fonctions locales
   methods: {},
   apollo: {
     idFromHash: {
-      query: gql`
-        query Search($hash: Hash!) {
-          idFromHash(hash: $hash) {
-            ...memberAttributes
-            pubkey
-            isLeaving
-            sentry
-            minDate
-            minDatePassed
-            membership_pending
-            limitDate
-            distance {
-              value {
-                ratio
-              }
-              dist_ok
-            }
-            received_certifications {
-              certifications {
-                from {
-                  ...memberAttributes
-                }
-                expires_on
-              }
-            }
-            sent_certifications {
-              to {
-                ...memberAttributes
-              }
-              expires_on
-            }
-          }
-        }
-        fragment memberAttributes on Identity {
-          uid
-          hash
-          status
-          quality {
-            ratio
-          }
-          received_certifications {
-            limit
-          }
-        }
-      `,
-      variables() {
-        return { hash: this.$route.params.hash };
-      },
-      skip() {
-        return false;
-      },
+      query: PREVISION,
+      variables() {return { hash: this.$route.params.hash }},
+      error (err) {this.error = err.message}
     },
   },
   computed: {
diff --git a/pages/previsions/index.vue b/pages/previsions/index.vue
index a24a77f1cabe81502885220788d1bee5667a252f..3a1f586d886cc8152ec67cc5fd13d27939398924 100644
--- a/pages/previsions/index.vue
+++ b/pages/previsions/index.vue
@@ -4,6 +4,7 @@
   <b-alert variant="danger" show>En développement</b-alert>
   <NavigationLoader :isLoading="$apollo.queries.test.loading" />
   <transition name="fade">
+    <div class="alert alert-danger" v-if="error">{{ error }}</div>
     <div v-if="test">
       {{ test }}
     </div>
@@ -12,13 +13,11 @@
 </template>
 
 <script>
-import gql from 'graphql-tag'
+import {PREVISIONS} from '@/graphql/queries'
 
 export default {
   data() {
-    // Variables locales
     return {
-      // Fil d'ariane
       breadcrumb: [
         {
           text: 'Accueil',
@@ -29,82 +28,21 @@ export default {
           active: true
         }
       ],
-      display: 'forecastsByNames'
+      display: 'forecastsByNames',
+      error: null
     }
-  },
-  // Fonctions locales
-  methods: {
-
   },
   apollo: {
     test : {
-      query: gql`query {
-        now {
-          number
-          bct
-        }
-        parameter(name: sigQty) {
-          sigQty:value
-        }
-        wwFile(full: true) {
-          certifs_dossiers {
-            ... on MarkedDatedCertification {
-              datedCertification {
-                date
-                certification {
-                  from {
-                    uid
-                  }
-                  to {
-                    uid
-                  }
-                  expires_on
-                }
-              }
-            }
-            ... on MarkedDossier {
-              dossier {
-                main_certifs
-                newcomer {
-                  uid
-                  lastApplication {
-                    lastAppDate: bct
-                  }
-                  distance: distanceE {
-                    value {
-                      ratio
-                    }
-                    dist_ok
-                  }
-                }
-                date
-                minDate
-                expires_on:limit
-                certifications {
-                  date
-                  certification {
-                    from {
-                      uid
-                      quality {
-                        ratio
-                      }
-                    }
-                    expires_on
-                  }
-                }
-              }
-            }
-          }
-        }
-      } `,
+      query: PREVISIONS,
       update (data) {
-
         return {
           now: data.now,
           sigQty: data.parameter.sigQty,
           certifs_dossiers: data.wwFile.certifs_dossiers
         }
-      }
+      },
+      error (err) {this.error = err.message}
     }
   },
   mounted () {
diff --git a/pages/previsions/newcomers.vue b/pages/previsions/newcomers.vue
index 34b8a85109e78856880f45dad07ade83e2fcd779..58784a5f41845dd6b26dceac5ae4eb9470288a96 100644
--- a/pages/previsions/newcomers.vue
+++ b/pages/previsions/newcomers.vue
@@ -2,7 +2,8 @@
 <main class="container">
   <NavigationLoader :isLoading="$apollo.queries.wwResult.loading" />
   <transition name="fade">
-    <div v-if="!$apollo.queries.wwResult.loading">
+    <div class="alert alert-danger" v-if="error">{{ error }}</div>
+    <div v-if="wwResult">
       <h2 class="text-center mb-5 font-weight-light">Prévisions <small><span class="badge badge-secondary">{{ wwResult.dossiers_nb }} dossiers en attente</span></small></h2>
       <div class="alert alert-info" role="alert">
         <ul class="list-unstyled m-0">
@@ -75,13 +76,11 @@
 </template>
 
 <script>
-import gql from 'graphql-tag'
+import {NEWCOMERS} from '@/graphql/queries'
 
 export default {
   data() {
-    // Variables locales
     return {
-      // Fil d'ariane
       breadcrumb: [
         {
           text: 'Accueil',
@@ -96,6 +95,7 @@ export default {
           active: true
         }
       ],
+      error: null,
       display: 'forecastsByNames'
     }
   },
@@ -107,28 +107,7 @@ export default {
   },
   apollo: {
     wwResult : {
-      query: gql`query {
-        wwResult {
-          permutations_nb
-          dossiers_nb
-          certifs_nb
-          forecastsByNames {
-            member : id {
-              pubkey
-              uid
-              status
-              hash
-              limitDate
-              received_certifications {
-                limit
-              }
-            }
-            date
-            after
-            proba
-          }
-        }
-      } `,
+      query: NEWCOMERS,
       update (data) {
         let result = {'byName':[],'byDate':[]}
         let forecasts = data.wwResult.forecastsByNames
@@ -182,7 +161,8 @@ export default {
           forecastsByNames: result['byName'],
           forecastsByDates: result['byDate']
         }
-      }
+      },
+      error (err) {this.error = err.message}
     }
   },
   mounted () {