diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 249801fc6cb1368eb2ef4b23b9de4436e80135bf..733b0ae02e7932c4091cd685c9758d638519c620 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -35,12 +35,16 @@ build_development:
     - npm install --unsafe-perm
     - echo -e "
       NODE_ENV=development\n
-      VUE_APP_LOCALE=fr-FR\n
       DOMAIN=https://dev.pigma.neogeo.fr/fr\n
       VUE_APP_DOMAIN=https://dev.pigma.neogeo.fr/\n
       BASE_PATH=/\n
-      VUE_APP_NEXT_DEFAULT=/\n
       VUE_APP_BASE_PATH=${BASE_PATH}\n
+      VUE_APP_NEXT_DEFAULT=/\n
+      VUE_APP_LOCALE=fr-FR\n
+      VUE_APP_I18N_LOCALE=fr\n
+      VUE_APP_I18N_DEFAULT_LOCALE=fr\n
+      VUE_APP_I18N_FALLBACK_LOCALE=fr\n
+      VUE_APP_I18N_SUPPORTED_LOCALE=fr,en\n
       VUE_APP_LOGO=@/assets/logo.png\n
       VUE_APP_TITLE=Login - Pigma\n
       VUE_APP_CLIENT_NAME=PIGMA\n
diff --git a/README.md b/README.md
index d0d9524fba051f1a9d826900513e8baa9e602768..a9716158319ac07bd5165ee2999f663e22de3495 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,6 @@ npm install
 
 ```ìni
 NODE_ENV=development
-VUE_APP_LOCALE=fr-FR
 
 DOMAIN=http://127.0.0.0:80
 VUE_APP_DOMAIN=${DOMAIN}
@@ -20,6 +19,12 @@ VUE_APP_BASE_PATH=${BASE_PATH}
 
 VUE_APP_NEXT_DEFAULT=${BASE_PATH}
 
+VUE_APP_LOCALE=fr-FR
+VUE_APP_I18N_LOCALE=fr
+VUE_APP_I18N_DEFAULT_LOCALE=fr
+VUE_APP_I18N_FALLBACK_LOCALE=fr
+VUE_APP_I18N_SUPPORTED_LOCALE=fr,en
+
 # App title
 VUE_APP_TITLE=Onegeo-Suite
 
diff --git a/package.json b/package.json
index 4394865b441ad37ba2ef730e20d55ea0b9e0f17f..52a1238bcd100649e4cf236773fcb20be48ac383 100644
--- a/package.json
+++ b/package.json
@@ -20,6 +20,7 @@
     "toastr": "^2.1.4",
     "vee-validate": "^3.4.9",
     "vue": "~2.6.11",
+    "vue-i18n": "^8.27.2",
     "vue-multiselect": "~2.1.6",
     "vue-recaptcha": "^1.3.0",
     "vue-router": "~3.2.0",
diff --git a/src/App.vue b/src/App.vue
index 23903416c543e0c48c7e0ffa2766ad95737f72eb..eeb0b42415b6be4ed2a470627690204efeaab68f 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -1,11 +1,18 @@
 <template>
   <div id="app">
+    <LocaleChanger />
     <router-view id="page"/>
   </div>
 </template>
 
 <script>
+import LocaleChanger from '@/components/LocaleChanger.vue';
+
 export default {
 
+  components: {
+    LocaleChanger
+  }
+
 };
 </script>
diff --git a/src/app.less b/src/app.less
index 75dd74149cbc4bf54ebcbdf8aefb8eb9b0448de3..5d913f59491c973151d9ef79f0967125627a5ff3 100644
--- a/src/app.less
+++ b/src/app.less
@@ -10,6 +10,12 @@ body {
   height: 100%;
 }
 
+#locale-changer {
+  position: absolute;
+  top: 1rem;
+  right: 5rem;
+}
+
 #page {
   height: 100%;
   overflow-y: auto;
diff --git a/src/assets/locales/en.json b/src/assets/locales/en.json
new file mode 100644
index 0000000000000000000000000000000000000000..d53beae93399499c2648e08760c1ad2c9ae9a6e5
--- /dev/null
+++ b/src/assets/locales/en.json
@@ -0,0 +1,195 @@
+{
+  "words": {
+    "username": "Username",
+    "password": "Password",
+    "firstname": "First name",
+    "lastname": "Last name",
+    "email": "E-mail address",
+    "phone": "Phone number",
+    "login": "Log in",
+    "logout": "Log out",
+    "validate": "Validate",
+    "cancel": "Cancel",
+    "retry": "Retry",
+    "accept": "Accept",
+    "decline": "Decline",
+    "save": "Save",
+    "goBack": "Go back",
+    "as": "as"
+  },
+  "errors": {
+    "required": "This field is required",
+    "email": "Please enter a valid email address",
+    "confirmPassword": "Passwords must be identical",
+    "regexPassword": "Your password must be at least 8 characters long, including at least one upper case, one lower case and one number."
+  },
+  "messages": {
+    "error": "An error has occured.",
+    "loginError": "Incorrect username and/or password",
+    "password": {
+      "success": "Your password has been changed."
+    },
+    "reinitPwdRequest": {
+      "success": "An e-mail has been sent to your mailbox to reset your password.",
+      "error": "No account found for this e-mail address."
+    },
+    "reinitPwdConfirm": {
+      "success": "Your password has been successfully reset. You will be redirected to the login page.",
+      "error": "Your token has expired. You must request a new one to change your password."
+    }
+  },
+  "multiselect": {
+    "noResult": "No results found",
+    "noOptions": "Enter the first characters..."
+  },
+  "importImage": {
+    "logo": "Add a logo",
+    "image": "Add an image",
+    "placeholder": "Upload file"
+  },
+  "organisationCreation": {
+    "title": "Create a new organisation",
+    "form": {
+      "name": "Organisation name",
+      "nameHelp": "Spelled out the entire name",
+      "acronym": "Acronym",
+      "siret": "Identification number",
+      "type": "Organisation type",
+      "typePlaceholder": "Select a type",
+      "logo": "Organisation logo",
+      "logoHelp": "Import a logo either in JPG or PNG format (maximum size: 2 MB)",
+      "web": "Website",
+      "phone": "Phone number",
+      "address": "Address",
+      "description": "Organisation description",
+      "group": {
+        "title": "Add this organisation to groups of organisations",
+        "help": "Adding this organisation to an organisation group will provide access to the data and data collections associated with that organisation group.",
+        "placeholder": "Add this organisation to groups of organisations"
+      }
+    }
+  },
+  "signin": {
+    "title": "Enter your {org} credentials",
+    "forgottenpassword": "Forgot your password",
+    "noaccount": "No account yet",
+    "warning": "You already had a {org} account and this is your first connection to the new platform? If so, for RGPD compliance reasons, you need to regenerate your password via the « Forgot your password? » link below. Please enter the email address linked to your {org} account. If you encounter a problem, please contact us at the following email address "
+  },
+  "forgottenPassword": {
+    "title": "Reset your password",
+    "message": "Please enter your account email address",
+    "placeholder": "Email address",
+    "confirmationButton": "Send reinitialization email"
+  },
+  "reinitPassword": {
+    "title": "Set a new Password",
+    "newLabel": "New password",
+    "confirmLabel": "Confirm password",
+    "passwordHelp": [
+      "Your password must be different from your personal information.",
+      "Your password must contain at least 8 characters.",
+      "Your password cannot be a commonly used password.",
+      "Your password cannot be entirely numerical."
+    ]
+  },
+  "signup": {
+    "title": "New account",
+    "subtitle": "Request an account",
+    "secondTitle": "A confirmation e-mail will be sent to your address",
+    "form": {
+      "personalDetails": {
+        "title": "Your personal details",
+        "reason": "Reason for registration"
+      },
+      "loginDetails": {
+        "title": "Your login details",
+        "usernameHelp": "The username is automatically generated from the first letter of your firstname and your lastname. It cannot be changed.",
+        "passwordHelp": [
+          "Your password must be different from your personal information.",
+          "Your password must contain at least 8 characters.",
+          "Your password cannot be a commonly used password.",
+          "Your password cannot be entirely numerical."
+        ]
+      },
+      "organisation": {
+        "title": "Organisation",
+        "subtitle": "Select your organisation from the list below.",
+        "placeholder": "Search for an organisation...",
+        "noOptions": "Enter an organisation's first characters to start the search",
+        "help": {
+          "text": "If you can't find it on the list, you can",
+          "link": " specify a new organisation."
+        }
+      }
+    }
+  },
+  "signupSuccess": {
+    "message": [
+      "A confirmation e-mail has just been sent to the address indicated on the form.",
+      "Please follow given instructions to finalize your account creation."
+    ]
+  },
+  "signout": {
+    "message": "You are now logged out.",
+    "toSignIn": "Go to login page"
+  },
+  "signoutFailed": {
+    "message": "An error occurred during signout."
+  },
+  "termsOfUse": {
+    "error": "An error has occurred. Please contact the site administrator.",
+    "download": "Download terms of use"
+  },
+  "profile": {
+    "title": "Existing account",
+    "subtitle": "Edit your account informations",
+    "form": {
+      "personalDetails": {
+        "title": "Your personal details",
+        "reason": "Reason for registration",
+        "organisation": {
+          "label": "Organisation(s)/Group(s)",
+          "noOrganisation": "You are not affiliated with any organisation.",
+          "help": "For any modification request, please contact"
+        }
+      },
+      "emailChange": {
+        "title": "Change your email address",
+        "label": "New email address",
+        "help": "You can request a change of your email address by entering a new address. A confirmation link will be sent to the new address."
+      },
+      "passwordChange": {
+        "title": "Change your password",
+        "oldLabel": "Old password",
+        "oldPlaceholder": "Old password",
+        "newLabel": "New password",
+        "newPlaceholder": "New password",
+        "confirmPlaceholder": "Confirm password",
+        "passwordHelp": [
+          "Your password must be different from your personal information.",
+          "Your password must contain at least 8 characters.",
+          "Your password cannot be a commonly used password.",
+          "Your password cannot be entirely numerical."
+        ]
+      }
+    }
+  },
+  "validationEmail": {
+    "message": "Your new email address has been validated.",
+    "goToLogin": "Go to login",
+    "error": "An error has occurred. Please contact the site administrator."
+  },
+  "validationRegistration": {
+    "messages": {
+      "success": [
+        "Thank you for your registration.",
+        "You will receive a notification when your account is enabled by the platform administrator."
+      ],
+      "error": "An error has occurred. Please contact the site administrator."
+    },
+    "confirmation": "To confirm your registration",
+    "clickHere": "Click here"
+  },
+  "footer": "Powered by",
+  "403": "Access Denied"
+}
\ No newline at end of file
diff --git a/src/assets/locales/fr.json b/src/assets/locales/fr.json
new file mode 100644
index 0000000000000000000000000000000000000000..59fcfb867d18c6999ecd4ba023de13af82086420
--- /dev/null
+++ b/src/assets/locales/fr.json
@@ -0,0 +1,196 @@
+{
+  "words": {
+    "username": "Nom d'utilisateur",
+    "password": "Mot de passe",
+    "firstname": "Prénom",
+    "lastname": "Nom",
+    "email": "Adresse e-mail",
+    "phone": "Numéro de téléphone",
+    "login": "Se connecter",
+    "logout": "Se déconnecter",
+    "validate": "Valider",
+    "cancel": "Annuler",
+    "retry": "Réessayer",
+    "accept": "Accepter",
+    "decline": "Refuser",
+    "save": "Sauvegarder",
+    "goBack": "Revenir",
+    "as": "en tant que"
+  },
+  "errors": {
+    "required": "Ce champ est requis",
+    "email": "Veuillez entrer une adresse e-mail valide",
+    "confirmPassword": "Les mots de passe doivent être identiques",
+    "regexPassword": "Votre mot de passe doit comporter au moins 8 caractères, dont au moins une majuscule, une minuscule et 1 chiffre."
+  },
+  "messages": {
+    "error": "Une erreur est survenue",
+    "loginError": "Nom d'utilisateur et/ou mot de passe incorrect(s)",
+    "password": {
+      "success": "Votre mot de passe a bien été modifié."
+    },
+    "reinitPwdRequest": {
+      "success": "Un e-mail vous a été envoyé sur votre messagerie pour réinitialiser votre mot de passe.",
+      "error": "Aucun compte trouvé pour cette adresse e-mail."
+    },
+    "reinitPwdConfirm": {
+      "success": "Votre mot de passe a bien été réinitialisé.  Vous allez être redirigé vers la page de connexion.",
+      "error": "Votre token a expiré. Vous devez en demander un nouveau pour changer votre mot de passe."
+    }
+  },
+  "multiselect": {
+    "noResult": "Aucun résultat.",
+    "noOptions": "Saississez les premiers caractères ..."
+  },
+  "importImage": {
+    "logo": "Ajouter un logo",
+    "image": "Ajouter un image",
+    "placeholder": "Importer un fichier"
+  },
+  "organisationCreation": {
+    "title": "Créer une nouvelle organisation",
+    "form": {
+      "name": "Nom de l'organisation",
+      "nameHelp": "Inscrivez le nom complet et en toutes lettres ; par ex. « Communauté des Communes Rurales de l'Entre-Deux-Mers »",
+      "acronym": "Sigle",
+      "siret": "Numéro SIRET",
+      "type": "Type d'organisation",
+      "typePlaceholder": "Sélectionnez un type",
+      "logo": "Logo de l'organisation",
+      "logoHelp": "Importez un logo au format JPG ou PNG (taille maximale : 2 Mo)",
+      "web": "Site internet",
+      "phone": "Numéro de téléphone",
+      "address": "Adresse postale",
+      "description": "description de l'organisation",
+      "group": {
+        "title": "Ajouter cette organisation à des groupe d'organisations",
+        "help": "L'ajout de cette organisation à un groupe d'organisation donnera accès aux données et collections de données associées à ce groupe d'organisation.",
+        "placeholder": "Ajouter cette organisation à des groupes d'organisations"
+      }
+    }
+  },
+  "signin": {
+    "title": "Saisissez vos identifiants {org}",
+    "forgottenpassword": "Mot de passe oublié",
+    "noaccount": "Pas encore de compte",
+    "warning": "Vous aviez déjà un compte {org} et il s’agit de votre première connexion sur la nouvelle plateforme ? Si tel est le cas, pour des raisons de conformité RGPD, il vous faut regénérer votre mot de passe via la fonction « Mot de passe oublié ? » disponible ci-dessous. Veuillez renseigner l’adresse mail liée à votre compte {org}. Si vous rencontrez un problème veuillez nous contacter à l’adresse mail suivante : "
+  },
+  "forgottenPassword": {
+    "title": "Réinitialisez votre mot de passe",
+    "message": "Veuillez indiquer l'adresse e-mail de votre compte",
+    "placeholder": "Adresse e-mail",
+    "confirmationButton": "Envoyer un e-mail de réinitialisation"
+
+  },
+  "reinitPassword": {
+    "title": "Choisissez un nouveau mot de passe",
+    "newLabel": "Nouveau mot de passe",
+    "confirmLabel": "Confirmez le mot de passe",
+    "passwordHelp": [
+      "Votre mot de passe ne peut pas ressembler à vos informations personnelles.",
+      "Votre mot de passe doit contenir au minimum 8 caractères.",
+      "Votre mot de passe ne peut pas être un mot de passe couramment utilisé.",
+      "Votre mot de passe ne peut pas être entièrement numérique."
+    ]
+  },
+  "signup": {
+    "title": "Nouveau compte",
+    "subtitle": "Sollicitez la création d'un compte",
+    "secondTitle": "Un e-mail de confirmation sera envoyé à l'adresse indiquée",
+    "form": {
+      "personalDetails": {
+        "title": "Vos informations personnelles",
+        "reason": "Motif de l'inscription"
+      },
+      "loginDetails": {
+        "title": "Vos identifiants",
+        "usernameHelp": "Le nom d'utilisateur est généré automatiquement à partir de la première lettre de votre prénom et de votre nom. Il n'est pas modifiable.",
+        "passwordHelp": [
+          "Votre mot de passe ne peut pas ressembler à vos informations personnelles.",
+          "Votre mot de passe doit contenir au minimum 8 caractères.",
+          "Votre mot de passe ne peut pas être un mot de passe couramment utilisé.",
+          "Votre mot de passe ne peut pas être entièrement numérique."
+        ]
+      },
+      "organisation": {
+        "title": "Organisation",
+        "subtitle": "Sélectionnez votre organisation dans la liste ci-dessous.",
+        "placeholder": "Recherchez une organisation ...",
+        "noOptions": "Saississez les premiers caractères d'une organisation pour lancer la recherche",
+        "help": {
+          "text": "Si celle-ci n'est pas dans la liste, vous pouvez",
+          "link": " indiquer une nouvelle organisation."
+        }
+      }
+    }
+  },
+  "signupSuccess": {
+    "message": [
+      "Un e-mail de confirmation vient d'être envoyé à l'adresse indiquée.",
+      "Merci de bien vouloir suivre les instructions données afin de finaliser la création de votre compte."
+    ]
+  },
+  "signout": {
+    "message": "Vous êtes maintenant déconnecté.",
+    "toSignIn": "Ouvrir la page de connexion"
+  },
+  "signoutFailed": {
+    "message": "Une erreur est survenue lors de la déconnexion."
+  },
+  "termsOfUse": {
+    "error": "Une erreur est survenue. Veuillez contacter l'administrateur du site.",
+    "download": "Télécharger les conditions d'utilisation"
+  },
+  "profile": {
+    "title": "Compte existant",
+    "subtitle": "Modifiez les informations relatives à votre compte",
+    "form": {
+      "personalDetails": {
+        "title": "Vos informations personnelles",
+        "reason": "Motif de l'inscription",
+        "organisation": {
+          "label": "Organisation(s)/Groupe(s)",
+          "noOrganisation": "Vous n'êtes rattaché à aucune organisation.",
+          "help": "Pour toute demande de modification, merci de contacter"
+        }
+      },
+      "emailChange": {
+        "title": "Changer votre adresse e-mail",
+        "label": "Nouvelle adresse e-mail",
+        "help": "Vous pouvez demander le changement de votre adresse mail en renseignant une nouvelle adresse. Un lien de confirmation vous sera envoyé sur la nouvelle adresse."
+      },
+      "passwordChange": {
+        "title": "Changer votre mot de passe",
+        "oldLabel": "Ancien mot de passe",
+        "oldPlaceholder": "Ancien mot de passe",
+        "newLabel": "Nouveau mot de passe",
+        "newPlaceholder": "Nouveau mot de passe",
+        "confirmPlaceholder": "Confirmez mot de passe",
+        "passwordHelp": [
+          "Votre mot de passe ne peut pas ressembler à vos informations personnelles.",
+          "Votre mot de passe doit contenir au minimum 8 caractères.",
+          "Votre mot de passe ne peut pas être un mot de passe couramment utilisé.",
+          "Votre mot de passe ne peut pas être entièrement numérique."
+        ]
+      }
+    }
+  },
+  "validationEmail": {
+    "message": "Votre nouvelle adresse e-mail est validée.",
+    "goToLogin": "Ouvrir la page de connexion",
+    "error": "Une erreur est survenue. Veuillez contacter l'administrateur du site."
+  },
+  "validationRegistration": {
+    "messages": {
+      "success": [
+        "Merci pour votre inscription.",
+        "Vous recevrez une notification lors de l'activation de votre compte par l'administrateur de la plateforme."
+      ],
+      "error": "Une erreur est survenue. Veuillez contacter l'administrateur du site."
+    },
+    "confirmation": "Pour confirmer votre inscription",
+    "clickHere": "Cliquez ici"
+  },
+  "footer": "Propulsé par",
+  "403": "Page non accessible"
+}
\ No newline at end of file
diff --git a/src/components/ImportImage.vue b/src/components/ImportImage.vue
index ac1b29467c0b470609476703ccb7fe1ac8d392b5..e0907712644e4bcec25f147f12824dfaa0104333 100644
--- a/src/components/ImportImage.vue
+++ b/src/components/ImportImage.vue
@@ -25,10 +25,10 @@
     >
       <img
         src="@/assets/icons/file_document_sheet.svg"
-        alt="Icône fichier"
+        alt="File icon"
       />
-      <div v-if="type === 'logo'"><b-icon-plus />Ajouter un logo</div>
-      <div v-if="type === 'image'"><b-icon-plus />Ajouter une image</div>
+      <div v-if="type === 'logo'"><b-icon-plus />{{ $t('importImage.logo') }}</div>
+      <div v-if="type === 'image'"><b-icon-plus />{{ $t('importImage.image') }}</div>
     </div>
     <div>
       <input
@@ -36,7 +36,7 @@
         :hidden="!(fileExist || filePreview)"
         type="file"
         accept="image/*"
-        placeholder="Importer un fichier"
+        placeholder="$t('importImage.placeholder')"
         @change="previewFile"
       >
     </div>
@@ -44,7 +44,6 @@
 </template>
 
 <script>
-import { mapState } from 'vuex';
 
 export default {
   name: 'ImportImage',
diff --git a/src/components/LocaleChanger.vue b/src/components/LocaleChanger.vue
new file mode 100644
index 0000000000000000000000000000000000000000..2cf517754386f3662af787b6a49b233d08496ca3
--- /dev/null
+++ b/src/components/LocaleChanger.vue
@@ -0,0 +1,37 @@
+<template>
+  <div id="locale-changer">
+    <select v-model="$i18n.locale">
+      <option
+        v-for="(lang, i) in langs"
+        :key="`Lang${i}`"
+        :value="lang"
+      >
+        {{ lang }}
+      </option>
+    </select>
+  </div>
+</template>
+
+<script>
+
+export default {
+
+  name: 'LocaleChanger',
+
+  data () {
+    return {
+      langs: ['fr', 'en'],
+    }
+  },
+
+  watch: {
+    '$i18n.locale': function(newValue, oldValue) {
+      if (newValue !== oldValue) {
+        const to = this.$router.resolve({ params: { locale: newValue } })
+        this.$router.push(to.location);
+      }
+    }
+  }
+
+}
+</script>
diff --git a/src/components/OrganisationCreation.vue b/src/components/OrganisationCreation.vue
index de088c4623a2aa0947cdd81b3b5c32ff7db33fc7..9f79368e7c59a97ad0e478a6e6a701c0e9418725 100644
--- a/src/components/OrganisationCreation.vue
+++ b/src/components/OrganisationCreation.vue
@@ -1,15 +1,15 @@
 <template>
   <div>
     <b-button-close @click="$emit('cancel')" class="close"/>
-    <h6>Créer une nouvelle organisation</h6>
+    <h6>{{ $t('organisationCreation.title') }}</h6>
     <br>
     <form>
       <div class="form-row">
         <div class="form-group col-11">
           <ValidationProvider rules="required" v-slot="{ classes, errors }">
             <div class="control" :class="classes">
-              <label class="required">Nom de l'organisation</label>
-              <p>Inscrivez le nom complet et en toutes lettres ; par ex. « Communauté des Communes Rurales de l'Entre-Deux-Mers »</p>
+              <label class="required">{{ $t('organisationCreation.form.name') }}</label>
+              <p>{{ $t('organisationCreation.form.nameHelp') }}</p>
               <input
                 v-model="formData.name"
                 class="form-control"
@@ -24,7 +24,7 @@
       <div class="form-row">
         <div class="form-group col-6">
           <div class="control">
-            <label>Sigle</label>
+            <label>{{ $t('organisationCreation.form.acronym') }}</label>
             <input
               v-model="formData.sigle"
               class="form-control"
@@ -36,7 +36,7 @@
       </div>
       <div class="form-row">
         <div class="form-group col-6">
-          <label>Numéro SIRET</label>
+          <label>{{ $t('organisationCreation.form.siret') }}</label>
           <input
             v-model="formData.siret"
             class="form-control"
@@ -49,7 +49,7 @@
         <div class="form-group col-6">
           <ValidationProvider rules="required" v-slot="{ classes, errors }">
             <div class="control" :class="classes">
-              <label class="required">Type d'organisation</label>
+              <label class="required">{{ $t('organisationCreation.form.type') }}</label>
               <Multiselect
                 v-model="formData.type"
                 :options="organisationsTypes"
@@ -59,7 +59,7 @@
                 selectedLabel=""
                 deselectLabel=""
                 :searchable="false"
-                placeholder="Sélectionnez un type"
+                :placeholder="$t('organisationCreation.form.typePlaceholder')"
               />
               <span class="form-errors">{{ errors[0] }}</span>
             </div>
@@ -68,8 +68,8 @@
       </div>
       <div class="form-row">
         <div class="form-group col-6">
-          <label>Logo de l'organisation</label>
-          <p>Importez un logo au format JPG ou PNG (taille maximale : 2 Mo)</p>
+          <label>{{ $t('organisationCreation.form.logo') }}</label>
+          <p>{{ $t('organisationCreation.form.logoHelp') }}</p>
           <ValidationProvider ref="thumbnail" v-slot="{ classes, errors }">
             <div class="control" :class="classes">
               <ImportImage
@@ -85,7 +85,7 @@
       </div>
       <div class="form-row">
         <div class="form-group col-9">
-          <label>Site internet</label>
+          <label>{{ $t('organisationCreation.form.web') }}</label>
           <input
             v-model="formData.web"
             class="form-control"
@@ -98,7 +98,7 @@
       </div>
       <div class="form-row">
         <div class="form-group col-6">
-          <label>Numéro de téléphone</label>
+          <label>{{ $t('organisationCreation.form.phone') }}</label>
           <input
             v-model="formData.tel"
             class="form-control"
@@ -109,7 +109,7 @@
       </div>
       <div class="form-row">
         <div class="form-group col-11">
-          <label>Adresse postale</label>
+          <label>{{ $t('organisationCreation.form.address') }}</label>
           <textarea
             v-model="formData.postalAddress"
             class="form-control"
@@ -118,7 +118,7 @@
       </div>
       <div class="form-row">
         <div class="form-group col-11">
-          <label>Description de l'organisation</label>
+          <label>{{ $t('organisationCreation.form.description') }}</label>
           <textarea
             v-model="formData.description"
             class="form-control"
@@ -128,13 +128,14 @@
       <div class="form-row">
         <div class="form-group col-11">
           <label>
-            Ajouter cette organisation à des groupe d'organisations
+            {{ $t('organisationCreation.form.group.title') }}
           </label>
           <p>
-            L'ajout de cette organisation à un groupe d'organisation donnera accès aux données et collections de données associées à ce groupe d'organisation.
+            {{ $t('organisationCreation.form.group.help') }}
           </p>
           <SearchUsergroups
             :type="'group-of-organisation'"
+            :placeholder="$t('organisationCreation.form.group.placeholder')"
             @select="addOrgToSphere"
           />
           <div
@@ -166,11 +167,12 @@ import {
   mapActions
 } from 'vuex';
 
+import i18n from '@/i18n';
+
 import ImportImage from '@/components/ImportImage';
 import SearchUsergroups from '@/components/SearchUsergroups';
 
 import {
-  ValidationObserver,
   ValidationProvider,
   extend,
   configure
@@ -182,7 +184,7 @@ import {
 
 extend('required', {
   ...required,
-  message: 'Ce champ est requis'
+  message: () => i18n.t('errors.required')
 });
 
 configure({
@@ -196,7 +198,6 @@ export default {
   name: 'OrganisationCreation',
 
   components: {
-    ValidationObserver,
     ValidationProvider,
     ImportImage,
     SearchUsergroups
diff --git a/src/components/OrganisationSelector.vue b/src/components/OrganisationSelector.vue
index cd036e616b31fd7d1c179080f7d84e46c8e2fa84..85498f4e3f89695900fc945b4707ecb62f960f96 100644
--- a/src/components/OrganisationSelector.vue
+++ b/src/components/OrganisationSelector.vue
@@ -1,9 +1,9 @@
 <template>
   <div>
-    <h5>Organisation</h5>
+    <h5>{{ $tc('signup.form.organisation.title') }}</h5>
     <hr class="divider" />
     <div v-if="!showCreationForm">
-      <label>Sélectionnez votre organisation dans la liste ci-dessous.</label>
+      <label>{{ $tc('signup.form.organisation.subtitle') }}</label>
       <Multiselect
         v-model="organisation"
         style="margin-top: 0.5em;"
@@ -18,7 +18,7 @@
         selectedLabel=""
         deselectLabel=""
         :searchable="true"
-        placeholder="Recherchez une organisation ..."
+        :placeholder="$tc('signup.form.organisation.placeholder')"
         :showNoResults="true"
         :loading="loading"
         :clearOnSelect="false"
@@ -35,16 +35,16 @@
           </div>
         </template>
         <span slot="noResult">
-          Aucun résultat.
+          {{ $t('multiselect.noResult') }}
         </span>
         <span slot="noOptions">
-          Saississez les premiers caractères d'une organisation pour lancer la recherche
+          {{ $t('signup.form.organisation.noOptions') }}
         </span>
       </Multiselect>
       <label>
-        Si celle-ci n'est pas dans la liste, vous pouvez
+        {{ $t('signup.form.organisation.help.text') }}
         <b-link @click="showCreationForm = true">
-          indiquer une nouvelle organisation.
+          {{ $t('signup.form.organisation.help.link') }}
         </b-link>
       </label>
     </div>
diff --git a/src/components/SearchUsergroups.vue b/src/components/SearchUsergroups.vue
index 58a4164ab5244a8fb085bee276651cb22bbc2ee5..7f9bd794621a67e57f5b97d2fcb0c1e34521b272 100644
--- a/src/components/SearchUsergroups.vue
+++ b/src/components/SearchUsergroups.vue
@@ -32,10 +32,10 @@
         </div>
       </template>
       <span slot="noResult">
-        Aucun résultat.
+        {{ $t('multiselect.noResult') }}
       </span>
       <span slot="noOptions">
-        Saisissez les premiers caractères ...
+        {{ $t('multiselect.noOptions') }}
       </span>
     </Multiselect>
   </div>
diff --git a/src/i18n.js b/src/i18n.js
new file mode 100644
index 0000000000000000000000000000000000000000..f61f8fa1db8750ad2b57b28cc9c0274ef2983bd3
--- /dev/null
+++ b/src/i18n.js
@@ -0,0 +1,69 @@
+import Vue from 'vue';
+import VueI18n from 'vue-i18n';
+
+import en from '@/assets/locales/en.json';
+import fr from '@/assets/locales/fr.json';
+
+// const defaultImpl = VueI18n.prototype.getChoiceIndex;
+
+// VueI18n.prototype.getChoiceIndex = function(choice, choicesLength) {
+//   // this === VueI18n instance, so the locale property also exists here
+//   if (this.locale !== 'fr') {
+//     // proceed to the default implementation
+//     return defaultImpl.apply(this, arguments)
+//   }
+
+//   if (choice === 0) {
+//     return 0;
+//   }
+
+//   const teen = choice > 10 && choice < 20;
+//   const endsWithOne = choice % 10 === 1;
+
+//   if (!teen && endsWithOne) {
+//     return 1;
+//   }
+
+//   if (!teen && choice % 10 >= 2 && choice % 10 <= 4) {
+//     return 2;
+//   }
+
+//   return (choicesLength < 4) ? 2 : 3;
+// }
+
+Vue.use(VueI18n);
+
+const dateTimeFormats = {
+  'en': {
+    short: {
+      year: 'numeric',
+      month: 'short',
+      day: 'numeric'
+    }
+  },
+  'fr': {
+    short: {
+      year: 'numeric',
+      month: 'numeric',
+      day: 'numeric'
+    }
+  }
+};
+
+const numberFormats = {
+  'fr': {
+    currency: {
+      style: 'currency', currency: 'EUR'
+    }
+  }
+};
+
+const i18n = new VueI18n({
+  locale: process.env.VUE_APP_I18N_DEFAULT_LOCALE || 'fr',
+  fallbackLocale: process.env.VUE_APP_I18N_FALLBACK_LOCALE || 'fr',
+  messages: { en, fr },
+  dateTimeFormats,
+  numberFormats
+});
+
+export default i18n;
diff --git a/src/main.js b/src/main.js
index 2a6a2499f4c07fd25b65bc6fcc759d08fe7209a4..70b2c34660bc793f025440641fbb74516175cf8a 100644
--- a/src/main.js
+++ b/src/main.js
@@ -13,12 +13,14 @@ Vue.use(BootstrapVueIcons);
 Vue.component('Multiselect', Multiselect);
 
 import App from '@/App.vue';
+import i18n from './i18n';
 import router from '@/router';
 import store from '@/store';
 
 Vue.config.productionTip = false;
 
 new Vue({
+  i18n,
   router,
   store,
   render: (h) => h(App),
diff --git a/src/router/index.js b/src/router/index.js
index 9e6e3eccacf66bffe621820728db2718fddf2375..93af3fe1ba25bdb17a1117cd3a4487c465543f00 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -1,73 +1,97 @@
 import Vue from 'vue';
 import VueRouter from 'vue-router';
+import i18n from '@/i18n';
 
 Vue.use(VueRouter);
 
 const routes = [
   {
-    path: '/',
-    redirect: { name: 'SignIn' },
+    path: '/:locale',
+    component: () => import('@/views/Base.vue'),
+    beforeEnter: (to, from, next) => {
+      const locale = to.params.locale;
+      const supported_locales = process.env.VUE_APP_I18N_SUPPORTED_LOCALE.split(',');
+      if (!supported_locales.includes(locale)) {
+        return next('fr');
+      }
+      if (i18n.locale !== locale) {
+        i18n.locale = locale;
+      }
+      return next();
+    },
+    children: [
+      {
+        path: '',
+        redirect: { name: 'SignIn' },
+      },
+      {
+        path: 'signin',
+        name: 'SignIn',
+        component: () => import('@/views/SignIn.vue'),
+      },
+      {
+        path: 'signup',
+        name: 'SignUp',
+        component: () => import('@/views/SignUp.vue'),
+      },
+      {
+        path: 'terms-of-use',
+        name: 'TermsOfUse',
+        component: () => import('@/views/TermsOfUse.vue'),
+      },
+      {
+        path: 'signout',
+        name: 'SignOut',
+        component: () => import('@/views/SignOut.vue'),
+      },
+      {
+        path: 'signout-failed',
+        name: 'SignOutFailed',
+        component: () => import('@/views/SignOutFailed.vue'),
+      },
+      {
+        path: 'signupsuccess',
+        name: 'SignUpSuccess',
+        component: () => import('@/views/SignUpSuccess.vue'),
+      },
+      {
+        path: 'validateregistration',
+        name: 'ValidationRegistration',
+        component: () => import('@/views/ValidationRegistration.vue'),
+      },
+      {
+        path: 'validate-email',
+        name: 'ValidationEmail',
+        component: () => import('@/views/ValidationEmail.vue'),
+      },
+      {
+        path: 'forgottenpwd',
+        name: 'ForgottenPassword',
+        component: () => import('@/views/ForgottenPassword.vue'),
+      },
+      {
+        path: 'reinitpwd',
+        name: 'ReinitPassword',
+        component: () => import('@/views/ReinitPassword.vue'),
+      },
+      {
+        path: 'profile',
+        name: 'UserProfile',
+        component: () => import('@/views/UserProfile.vue'),
+      },
+      {
+        path: '*',
+        name: 'NotFound',
+        component: () => import('@/views/NotFound.vue'),
+      },
+    ]
   },
   {
-    path: '/signin',
-    name: 'SignIn',
-    component: () => import('@/views/SignIn.vue'),
-  },
-  {
-    path: '/signup',
-    name: 'SignUp',
-    component: () => import('@/views/SignUp.vue'),
-  },
-  {
-    path: '/terms-of-use',
-    name: 'TermsOfUse',
-    component: () => import('@/views/TermsOfUse.vue'),
-  },
-  {
-    path: '/signout',
-    name: 'SignOut',
-    component: () => import('@/views/SignOut.vue'),
-  },
-  {
-    path: '/signout-failed',
-    name: 'SignOutFailed',
-    component: () => import('@/views/SignOutFailed.vue'),
-  },
-  {
-    path: '/signupsuccess',
-    name: 'SignUpSuccess',
-    component: () => import('@/views/SignUpSuccess.vue'),
-  },
-  {
-    path: '/validateregistration',
-    name: 'ValidationRegistration',
-    component: () => import('@/views/ValidationRegistration.vue'),
-  },
-  {
-    path: '/validate-email',
-    name: 'ValidationEmail',
-    component: () => import('@/views/ValidationEmail.vue'),
-  },
-  {
-    path: '/forgottenpwd',
-    name: 'ForgottenPassword',
-    component: () => import('@/views/ForgottenPassword.vue'),
-  },
-  {
-    path: '/reinitpwd',
-    name: 'ReinitPassword',
-    component: () => import('@/views/ReinitPassword.vue'),
-  },
-  {
-    path: '/profile',
-    name: 'UserProfile',
-    component: () => import('@/views/UserProfile.vue'),
-  },
-  {
-    path: '/*',
-    name: 'NotFound',
-    component: () => import('@/views/NotFound.vue'),
-  },
+    path: '*',
+    redirect() {
+      return process.env.VUE_APP_I18N_DEFAULT_LOCALE;
+    }
+  }
 ];
 
 const router = new VueRouter({
diff --git a/src/store/modules/forgotten-pwd.store.js b/src/store/modules/forgotten-pwd.store.js
index bb39585875c45520b054436eded51d652e121e8b..d9338ef7b70723c80abf46b0f9ba76f85e7e6370 100644
--- a/src/store/modules/forgotten-pwd.store.js
+++ b/src/store/modules/forgotten-pwd.store.js
@@ -3,6 +3,7 @@ import { ErrorService } from '@/services/error-service.js';
 import Swal from "sweetalert2";
 import "sweetalert2/dist/sweetalert2.min.css";
 import router from '@/router';
+import i18n from '@/i18n';
 
 const state = {
   error: null,
@@ -23,9 +24,7 @@ const actions = {
         position: 'center',
         heightAuto: false,
         icon: 'success',
-        text: `
-          Un e-mail vous a été envoyé sur votre messagerie pour réinitialiser votre mot de passe.
-        `,
+        text: i18n.t('messages.reinitPwdRequest.success'),
         showConfirmButton: true,
         confirmButtonText: 'OK',
         confirmButtonColor: '#187CC6'
@@ -38,7 +37,7 @@ const actions = {
     if (response.status === 404) {
       commit('SET_ERROR', {
         response: response,
-        message: 'Aucun compte trouvé pour cette adresse e-mail.'
+        message: i18n.t('messages.reinitPwdRequest.error')
       });
     }
   },
@@ -50,9 +49,7 @@ const actions = {
         position: 'center',
         heightAuto: false,
         icon: 'success',
-        text: `Votre mot de passe a bien été réinitialisé.
-          Vous allez être redirigé vers la page de connexion.
-        `,
+        text: i18n.t('messages.reinitPwdConfirm.success'),
         showConfirmButton: true,
         confirmButtonText: 'OK',
         confirmButtonColor: '#187CC6'
@@ -66,9 +63,7 @@ const actions = {
         position: 'center',
         heightAuto: false,
         icon: 'error',
-        text: `Votre token a expiré. Vous devez en demander un nouveau 
-          pour changer votre mot de passe.
-        `,
+        text: i18n.t('messages.reinitPwdConfirm.error'),
         showConfirmButton: true,
         confirmButtonText: 'OK',
         confirmButtonColor: '#187CC6'
diff --git a/src/store/modules/sign-in.store.js b/src/store/modules/sign-in.store.js
index fb3bd4cbd2169976a3b782e8ca2e5af217734584..89cb53d1234678ddbec8b07e883009c8ec5e87b5 100644
--- a/src/store/modules/sign-in.store.js
+++ b/src/store/modules/sign-in.store.js
@@ -1,4 +1,5 @@
 import client from '@/api/loginAPI.js';
+import i18n from '@/i18n';
 
 const state = {
   username: null,
@@ -32,7 +33,7 @@ const actions = {
             commit(
               'SET_ERROR',
               error.response.data.detail
-              || 'Nom d\'utilisateur et/ou mot de passe incorrect(s)',
+              || i18n.t('messages.loginError'),
             );
             commit('SET_LOGGED', false);
           }
diff --git a/src/store/modules/sign-out.store.js b/src/store/modules/sign-out.store.js
index f9377c8c422164625d37646d779795fe134e8ea4..b60d81a0820a932994756721304964ea7c95c248 100644
--- a/src/store/modules/sign-out.store.js
+++ b/src/store/modules/sign-out.store.js
@@ -1,4 +1,5 @@
 import client from '@/api/loginAPI.js';
+import i18n from '@/i18n';
 
 const state = {
   logged: null,
@@ -24,7 +25,7 @@ const actions = {
           commit(
             'SET_ERROR',
             error.response.data
-            || 'Une erreur est survenue',
+            || i18n.t('messages.error'),
           );
           commit('SET_LOGGED', true);
         },
diff --git a/src/store/modules/sign-up.store.js b/src/store/modules/sign-up.store.js
index 12a14472901f60eeaa9ced5ea6bfa8ae44074ae2..494845bf7b2adfdf6e94dd6f6c916e1a288b0761 100644
--- a/src/store/modules/sign-up.store.js
+++ b/src/store/modules/sign-up.store.js
@@ -1,6 +1,7 @@
 import client from '@/api/loginAPI.js';
 import organisationAPI from '@/api/organisationsAPI.js';
 import usergroupsAPI from '@/api/usergroupsAPI.js';
+import i18n from '@/i18n';
 
 import { ErrorService } from '@/services/error-service.js';
 
@@ -43,7 +44,7 @@ const actions = {
               commit(
                 'SET_ERROR',
                 error.response
-                || 'Une erreur est survenue',
+                || i18n.t('messages.error'),
               );
               commit('SET_SIGNED', false);
             });
@@ -68,7 +69,7 @@ const actions = {
               commit(
                 'SET_ERROR',
                 error.response
-                || 'Une erreur est survenue',
+                || i18n.t('messages.error'),
               );
               commit('SET_SIGNED', false);
             });
@@ -82,7 +83,7 @@ const actions = {
           commit(
             'SET_ERROR',
             error.response
-            || 'Une erreur est survenue',
+            || i18n.t('messages.error'),
           );
           commit('SET_SIGNED', false);
         },
diff --git a/src/store/modules/terms-of-use.store.js b/src/store/modules/terms-of-use.store.js
index 076d29fb39b23ab5aaad2a6cb6389ebbe914dcac..6d5f30a1548449223d59e918ecad5ac00b0fca45 100644
--- a/src/store/modules/terms-of-use.store.js
+++ b/src/store/modules/terms-of-use.store.js
@@ -1,6 +1,7 @@
 import client from '@/api/loginAPI.js';
 import { ErrorService } from '@/services/error-service.js';
 import router from '@/router';
+import i18n from '@/i18n';
 
 const state = {
   terms: null,
@@ -27,7 +28,7 @@ const actions = {
     if (response.status === 404) {
       commit('SET_ERROR', {
         response: response,
-        message: 'Une erreur est survenue.'
+        message: i18n.t('messages.error')
       });
     }
   },
@@ -43,7 +44,7 @@ const actions = {
     if (response.status === 404) {
       commit('SET_ERROR', {
         response: response,
-        message: 'Une erreur est survenue.'
+        message: i18n.t('messages.error')
       });
     }
   }
diff --git a/src/store/modules/user.store.js b/src/store/modules/user.store.js
index e5b7ea602ced121c19f62093929fbf4f95df33a9..632050e334ab1f67342a584270f46263240ec1a2 100644
--- a/src/store/modules/user.store.js
+++ b/src/store/modules/user.store.js
@@ -1,6 +1,7 @@
 import loginAPI from '@/api/loginAPI.js';
 
 import { ErrorService } from '@/services/error-service.js';
+import i18n from '@/i18n';
 
 // MUTATIONS
 export const SET_ERROR = 'SET_ERROR';
@@ -68,7 +69,7 @@ const actions = {
         commit('SET_ERROR', null);
         commit('SET_SUCCESS', {
           response: resp,
-          message: 'Votre mot de passe a bien été modifié.'
+          message: i18n.t('messages.password.success')
         });
       }
     })
diff --git a/src/views/Base.vue b/src/views/Base.vue
new file mode 100644
index 0000000000000000000000000000000000000000..0afb5bdcf92765b35f1863a28418ce7d9aaa2fea
--- /dev/null
+++ b/src/views/Base.vue
@@ -0,0 +1,9 @@
+<template>
+  <router-view />
+</template>
+
+<script>
+export default {
+  name: 'Base'
+}
+</script>
\ No newline at end of file
diff --git a/src/views/ForgottenPassword.vue b/src/views/ForgottenPassword.vue
index 8c1cef9c36adbbaebc2e7d66b479f585b90cd933..787f46691f88085ba7806e0985ce13cbb5f9a36e 100644
--- a/src/views/ForgottenPassword.vue
+++ b/src/views/ForgottenPassword.vue
@@ -5,17 +5,17 @@
         <img alt="logo" :src="logoPath"/>
       </div>
       <div class="form">
-        <h5 class="title">Réinitialisez votre mot de passe</h5>
+        <h5 class="title">{{ $t('forgottenPassword.title') }}</h5>
         <form>
           <div class="form-row">
             <label>
-              Veuillez indiquer l'adresse e-mail de votre compte
+              {{ $t('forgottenPassword.message') }}
             </label>
             <input
               v-model="email"
               class="form-control"
               type="text"
-              placeholder="Adresse e-mail"
+              :placeholder="$t('forgottenPassword.placeholder')"
             >
           </div>
           <button
@@ -23,12 +23,12 @@
             class="btn btn-primary"
             @click.prevent="reinitPassword"
           >
-            Envoyer un e-mail de réinitialisation
+            {{ $t('forgottenPassword.confirmationButton') }}
           </button>
           <button
             class="btn btn-outline-secondary"
             @click="$router.push({ name: 'SignIn' })">
-            Annuler
+            {{ $t('words.cancel') }}
           </button>
         </form>
       </div>
@@ -39,7 +39,7 @@
       </div>
     </div>
     <small class="footer">
-      <p>Propulsé par <a href="https://www.neogeo.fr/" target="_blank" rel="noopener">Neogeo-Technologies</a></p>
+      <p>{{ $t('footer') }} <a href="https://www.neogeo.fr/" target="_blank" rel="noopener">Neogeo-Technologies</a></p>
     </small>
   </div>
 </template>
diff --git a/src/views/ReinitPassword.vue b/src/views/ReinitPassword.vue
index af22675d2f0054bb0cc8c7d6ccb1354a4cc51c95..1068e01ed8f5092e08a90b56056d6dec68270abc 100644
--- a/src/views/ReinitPassword.vue
+++ b/src/views/ReinitPassword.vue
@@ -15,8 +15,8 @@
       >
       </b-overlay>
       <div class="form">
-        <h5 class="title">Choisissez un nouveau mot de passe</h5>
-        <ValidationObserver v-slot="{ handleSubmit }">
+        <h5 class="title">{{ $t('reinitPassword.title') }}</h5>
+        <ValidationObserver ref="form" v-slot="{ handleSubmit }">
           <form>
             <div class="form-row">
               <ValidationProvider
@@ -27,14 +27,14 @@
               >
                 <div class="control" :class="classes">
                   <label class="required">
-                    Nouveau de mot de passe
+                    {{ $t('reinitPassword.newLabel') }}
                   </label>
                   <div class="input-group flex-nowrap">
                     <input
                       v-model="password1"
                       class="form-control"
                       :type="showPassword ? 'text' : 'password'"
-                      placeholder="Mot de passe"
+                      :placeholder="$t('words.password')"
                     >
                     <span
                       v-if="!showPassword"
@@ -63,14 +63,14 @@
               <ValidationProvider ref="password" rules="required|confirmed:confirmation" v-slot="{ classes, errors }">
                 <div class="control" :class="classes">
                   <label class="required">
-                    Confirmez le mot de passe
+                    {{ $t('reinitPassword.confirmLabel') }}
                   </label>
                   <div class="input-group flex-nowrap">
                     <input
                       v-model="password2"
                       class="form-control"
                       :type="showPassword ? 'text' : 'password'"
-                      placeholder="Mot de passe"
+                      :placeholder="$t('words.password')"
                     >
                     <span
                       v-if="!showPassword"
@@ -97,10 +97,10 @@
             </div>
             <div class="infos">
               <ul>
-                <li>Votre mot de passe ne peut pas trop ressembler à vos autres informations personnelles.</li>
-                <li>Votre mot de passe doit contenir au minimum 8 caractères.</li>
-                <li>Votre mot de passe ne peut pas être un mot de passe couramment utilisé.</li>
-                <li>Votre mot de passe ne peut pas être entièrement numérique.</li>
+                <li>{{ $t('reinitPassword.passwordHelp')[0] }}</li>
+                <li>{{ $t('reinitPassword.passwordHelp')[1] }}</li>
+                <li>{{ $t('reinitPassword.passwordHelp')[2] }}</li>
+                <li>{{ $t('reinitPassword.passwordHelp')[3] }}</li>
               </ul>
             </div>
             <button
@@ -108,14 +108,14 @@
               class="btn btn-primary"
               @click.prevent="handleSubmit(sendNewPassword)"
             >
-              Sauvegarder
+              {{ $t('words.save') }}
             </button>
             <button
               type="button"
               class="btn btn-outline-secondary"
               @click="$router.push({ name: 'SignIn' })"
             >
-              Annuler
+              {{ $t('words.cancel') }}
             </button>
           </form>
         </ValidationObserver>
@@ -130,7 +130,7 @@
       </div>
     </div>
     <small class="footer">
-      <p>Propulsé par <a href="https://www.neogeo.fr/" target="_blank" rel="noopener">Neogeo-Technologies</a></p>
+      <p>{{ $t('footer') }} <a href="https://www.neogeo.fr/" target="_blank" rel="noopener">Neogeo-Technologies</a></p>
     </small>
   </div>
 </template>
@@ -138,6 +138,8 @@
 <script>
 import { mapState, mapActions } from 'vuex';
 
+import i18n from '@/i18n';
+
 import {
   ValidationObserver,
   ValidationProvider,
@@ -149,12 +151,12 @@ import { required, confirmed, regex } from 'vee-validate/dist/rules';
 
 extend('required', {
   ...required,
-  message: 'Ce champ est requis',
+  message: () => i18n.t('errors.required'),
 });
 
 extend('confirmed', {
   ...confirmed,
-  message: 'Les mots de passe doivent être identiques',
+  message: () => i18n.t('errors.confirmPassword'),
 });
 
 configure({
@@ -166,7 +168,7 @@ configure({
 
 extend('regex', {
   ...regex,
-  message: 'Votre mot de passe doit comporter au moins 8 caractères, dont au moins une majuscule, une minuscule et 1 chiffre.',
+  message: i18n.t('errors.regexPassword'),
 });
 
 export default {
@@ -190,7 +192,19 @@ export default {
     ...mapState('forgotten-pwd', [
       'error',
       'success'
-    ])
+    ]),
+
+    logoPath() {
+      return require(process.env.VUE_APP_LOGO);
+    }
+  },
+
+  watch: {
+    '$i18n.locale': function(newValue, oldValue) {
+      if (newValue !== oldValue) {
+        this.$refs.form.validate();
+      }
+    },
   },
 
   methods: {
diff --git a/src/views/SignIn.vue b/src/views/SignIn.vue
index 32f0ad7a08e5fd05ac9eef3d5cfad1098d726718..20404fffeea14314e7cffde21b26157dc70766f1 100644
--- a/src/views/SignIn.vue
+++ b/src/views/SignIn.vue
@@ -5,14 +5,14 @@
         <img alt="logo" :src="logoPath"/>
       </div>
       <div class="sign-in-form">
-        <h5 class="title">Saississez vos identifiants {{ clientName }}</h5>
+        <h5 class="title">{{ $t('signin.title', { org: clientName}) }}</h5>
         <form>
           <div class="form-row">
             <input
               v-model="form.username"
               class="form-control"
               type="text"
-              placeholder="Nom d'utilisateur"
+              :placeholder="$t('words.username')"
               v-on:keydown.enter.prevent="submit"
             >
           </div>
@@ -22,7 +22,7 @@
                 v-model="form.password"
                 class="form-control"
                 :type="showPassword ? 'text' : 'password'"
-                placeholder="Mot de passe"
+                :placeholder="$t('words.password')"
                 v-on:keydown.enter.prevent="submit"
               >
               <span
@@ -58,7 +58,7 @@
               variant="primary"
               block
             >
-              Se connecter
+              {{ $t('words.login') }}
             </b-button>
           </div>
           <div class="form-row attention-message">
@@ -67,27 +67,23 @@
               height="100"
             />
             <p>
-              Vous aviez déjà un compte {{ clientName }} et il s’agit de votre première connexion sur la nouvelle plateforme ?
-              Si tel est le cas, pour des raisons de conformité RGPD, il vous faut regénérer votre mot de passe via 
-              la fonction « Mot de passe oublié ? » disponible ci-dessous.
-              Veuillez renseigner l’adresse mail liée à votre compte {{ clientName }}.
-              Si vous rencontrez un problème veuillez nous contacter à l’adresse mail suivante : 
+              {{ $t('signin.warning', { org: clientName }) }}
               <a :href="`mailto:${clientMail}`">{{ clientMail }}</a>
             </p>
           </div>
           <div class="form-row">
             <div class="btn-group-vertical">
               <router-link
-                to="/signup"
+                to="signup"
                 custom
               >
-                Pas encore de compte ?
+                {{ $t('signin.noaccount') }} ?
               </router-link>
               <router-link
-                to="/forgottenpwd"
+                to="forgottenpwd"
                 custom
               >
-                Mot de passe oublié ?
+                {{ $t('signin.forgottenpassword') }} ?
               </router-link>
             </div>
           </div>
@@ -95,7 +91,7 @@
       </div>
     </div>
     <small class="footer">
-      <p>Propulsé par <a href="https://www.neogeo.fr/" target="_blank" rel="noopener">Neogeo-Technologies</a></p>
+      <p>{{ $t('footer') }} <a href="https://www.neogeo.fr/" target="_blank" rel="noopener">Neogeo-Technologies</a></p>
     </small>
   </div>
 </template>
diff --git a/src/views/SignOut.vue b/src/views/SignOut.vue
index e7c432ba6caf81412c5468677e057c05c1c44b3f..25c23b2183092582af2f58e5268d6ad9637b2830 100644
--- a/src/views/SignOut.vue
+++ b/src/views/SignOut.vue
@@ -6,15 +6,15 @@
     <div class="center">
       <b-container class="msg">
         <p>
-          Vous êtes maintenant déconnecté.<br>
+          {{ $t('signout.message') }}<br>
         </p>
         <b-button type="button" variant="outline-primary" @click.prevent="$router.push({ name: 'SignIn' })">
-          Ouvrir la page de connexion
+          {{ $t('signout.toSignIn') }}
         </b-button>
       </b-container>
     </div>
     <small class="footer">
-      <p>Propulsé par <a href="https://www.neogeo.fr/" target="_blank" rel="noopener">Neogeo-Technologies</a></p>
+      <p>{{ $t('footer') }} <a href="https://www.neogeo.fr/" target="_blank" rel="noopener">Neogeo-Technologies</a></p>
     </small>
   </div>
 </template>
diff --git a/src/views/SignOutFailed.vue b/src/views/SignOutFailed.vue
index fecd5de903398fce23cc8af88011fafffb70bd82..2b605523fae5afd435b4805b2c25f8320865c132 100644
--- a/src/views/SignOutFailed.vue
+++ b/src/views/SignOutFailed.vue
@@ -19,12 +19,12 @@
           Une erreur est survenue lors de la déconnexion.<br>
         </p>
         <b-button type="button" variant="outline-primary" @click.prevent="retrySignout">
-          Réessayer
+          {{ $t('words.retry') }}
         </b-button>
       </b-container>
     </div>
     <small class="footer">
-      <p>Propulsé par <a href="https://www.neogeo.fr/" target="_blank" rel="noopener">Neogeo-Technologies</a></p>
+      <p>{{ $t('footer') }} <a href="https://www.neogeo.fr/" target="_blank" rel="noopener">Neogeo-Technologies</a></p>
     </small>
   </div>
 </template>
diff --git a/src/views/SignUp.vue b/src/views/SignUp.vue
index b267c60be26e0b0b35d82564401430ad1371aad0..5c7d51e68c9081102a4dc41479a4b392f59729ed 100644
--- a/src/views/SignUp.vue
+++ b/src/views/SignUp.vue
@@ -16,18 +16,18 @@
       </b-overlay>
       <div class="signup-form">
         <h4 class="title">
-          Nouveau compte
-          <span class="sub-title">Sollicitez la création d'un compte</span>
+          {{ $t('signup.title') }}
+          <span class="sub-title">{{ $t('signup.subtitle') }}</span>
         </h4>
         <hr class="divider">
-        <h5>Un e-mail de confirmation sera envoyé à l'adresse indiquée</h5>
-        <ValidationObserver v-slot="{ handleSubmit }">
+        <h5>{{ $t('signup.secondTitle') }}</h5>
+        <ValidationObserver ref="form" v-slot="{ handleSubmit }">
         <form>
-          <h5>Vos informations personnelles</h5>
+          <h5>{{ $t('signup.form.personalDetails.title') }}</h5>
           <hr class="divider">
           <div class="row g-2 align-items-center">
             <div class="col-3">
-              <label class="col-form-label required">Prénom</label>
+              <label class="col-form-label required">{{ $t('words.lastname') }}</label>
             </div>
             <div class="col">
               <ValidationProvider ref="first_name" rules="required" v-slot="{ classes, errors }">
@@ -36,7 +36,7 @@
                     v-model="form.first_name"
                     type="text"
                     class="form-control"
-                    placeholder="Prénom"
+                    :placeholder="$t('words.firstname')"
                   >
                   <span class="form-errors">{{ errors[0] }}</span>
                 </div>
@@ -45,7 +45,7 @@
           </div>
           <div class="row g-2 align-items-center">
             <div class="col-3">
-              <label class="col-form-label required">Nom</label>
+              <label class="col-form-label required">{{ $t('words.lastname') }}</label>
             </div>
             <div class="col">
               <ValidationProvider ref="last_name" rules="required" v-slot="{ classes, errors }">
@@ -54,7 +54,7 @@
                     v-model="form.last_name"
                     type="text"
                     class="form-control"
-                    placeholder="Nom"
+                     :placeholder="$t('words.lastname')"
                   >
                   <span class="form-errors">{{ errors[0] }}</span>
                 </div>
@@ -63,7 +63,7 @@
           </div>
           <div class="row g-2 align-items-center">
             <div class="col-3">
-              <label class="col-form-label required">Adresse e-mail</label>
+              <label class="col-form-label required">{{ $t('words.email') }}</label>
             </div>
             <div class="col">
               <ValidationProvider ref="email" rules="required|email" v-slot="{ classes, errors }">
@@ -72,7 +72,7 @@
                     v-model="form.email"
                     type="mail"
                     class="form-control"
-                    placeholder="Adresse e-mail"
+                    :placeholder="$t('words.email')"
                   >
                   <span class="form-errors">{{ errors[0] }}</span>
                 </div>
@@ -81,7 +81,7 @@
           </div>
           <div class="row g-2 align-items-center">
             <div class="col-3">
-              <label class="col-form-label">Numéro de téléphone</label>
+              <label class="col-form-label">{{ $t('words.phone') }}</label>
             </div>
             <div class="col">
               <ValidationProvider ref="phone_number" v-slot="{ classes, errors }">
@@ -99,7 +99,9 @@
           </div>
           <div class="row g-2 align-items-center">
             <div class="col-3">
-              <label class="col-form-label">Motif de l'inscription</label>
+              <label class="col-form-label">
+                {{ $t('signup.form.personalDetails.reason') }}
+              </label>
             </div>
             <div class="col">
               <textarea
@@ -108,11 +110,11 @@
               />
             </div>
           </div>
-          <h5>Vos identifiants</h5>
+          <h5>{{ $t('signup.form.loginDetails.title') }}</h5>
           <hr class="divider">
           <div class="row g-2 align-items-center">
             <div class="col-3">
-              <label class="col-form-label">Nom d'utilisateur</label>
+              <label class="col-form-label">{{ $t('words.username') }}</label>
             </div>
             <div class="col">
               <ValidationProvider ref="username" rules="required" v-slot="{ classes, errors }">
@@ -138,9 +140,7 @@
             </div>
             <div class="col">
               <p class="infos">
-                Le nom d'utilisateur est généré automatiquement à partir de la 
-                première lettre de votre prénom et de votre nom.
-                Il n'est pas modifiable.
+                {{ $t('signup.form.loginDetails.usernameHelp') }}
               </p>
             </div>
           </div>
@@ -149,7 +149,7 @@
               <label
                 class="col-form-label required"
                 style="padding: 0;"
-              >Mot de passe
+              >{{ $t('words.password') }}
               </label>
             </div>
             <div class="col">
@@ -165,7 +165,7 @@
                       v-model="form.password1"
                       class="form-control"
                       :type="showPassword ? 'text' : 'password'"
-                      placeholder="Mot de passe"
+                      :placeholder="$t('words.password')"
                     >
                     <span
                       v-if="!showPassword"
@@ -201,7 +201,7 @@
                       v-model="form.password2"
                       class="form-control"
                       :type="showPassword ? 'text' : 'password'"
-                      placeholder="Mot de passe"
+                      :placeholder="$t('words.password')"
                     >
                     <span
                       v-if="!showPassword"
@@ -233,10 +233,10 @@
             <div class="col">
               <div class="infos">
                 <ul>
-                  <li>Votre mot de passe ne peut pas ressembler à vos informations personnelles.</li>
-                  <li>Votre mot de passe doit contenir au minimum 8 caractères.</li>
-                  <li>Votre mot de passe ne peut pas être un mot de passe couramment utilisé.</li>
-                  <li>Votre mot de passe ne peut pas être entièrement numérique.</li>
+                  <li>{{ $t('signup.form.loginDetails.passwordHelp')[0] }}</li>
+                  <li>{{ $t('signup.form.loginDetails.passwordHelp')[1] }}</li>
+                  <li>{{ $t('signup.form.loginDetails.passwordHelp')[2] }}</li>
+                  <li>{{ $t('signup.form.loginDetails.passwordHelp')[3] }}</li>
                 </ul>
               </div>
             </div>
@@ -248,10 +248,10 @@
             @click.prevent="handleSubmit(submit)"
             variant="primary"
           >
-            Valider
+            {{ $t('words.validate') }}
           </b-button>
           <b-button type="button" variant="outline-primary" @click.prevent="$router.push({ name: 'SignIn' })">
-            Annuler
+            {{ $t('words.cancel') }}
           </b-button>
         </form>
         </ValidationObserver>
@@ -259,7 +259,7 @@
     </div>
     <small class="footer">
       <p>
-        Propulsé par <a href="https://www.neogeo.fr/" target="_blank" rel="noopener">Neogeo-Technologies</a>
+        {{ $t('footer') }} <a href="https://www.neogeo.fr/" target="_blank" rel="noopener">Neogeo-Technologies</a>
       </p>
     </small>
   </div>
@@ -290,6 +290,8 @@ import OrganisationSelector from '@/components/OrganisationSelector';
 
 import { deburr } from 'lodash';
 
+import i18n from '@/i18n';
+
 import {
   ValidationObserver,
   ValidationProvider,
@@ -301,22 +303,22 @@ import { required, email, confirmed, regex } from 'vee-validate/dist/rules';
 
 extend('required', {
   ...required,
-  message: 'Ce champ est requis',
+  message: () => i18n.t('errors.required'),
 });
 
 extend('email', {
   ...email,
-  message: 'Veuillez entrer une adresse e-mail valide',
+  message: () => i18n.t('errors.email'),
 });
 
 extend('confirmed', {
   ...confirmed,
-  message: 'Les mots de passe doivent être identiques',
+  message: () => i18n.t('errors.confirmPassword'),
 });
 
 extend('regex', {
   ...regex,
-  message: 'Votre mot de passe doit comporter au moins 8 caractères, dont au moins une majuscule, une minuscule et 1 chiffre.',
+  message: () => i18n.t('errors.regexPassword'),
 });
 
 configure({
@@ -368,6 +370,12 @@ export default {
     }
   },
   watch: {
+    '$i18n.locale': function(newValue, oldValue) {
+      if (newValue !== oldValue) {
+        this.$refs.form.validate();
+      }
+    },
+
     'form.first_name': {
       deep: true,
       handler(newValue) {
diff --git a/src/views/SignUpSuccess.vue b/src/views/SignUpSuccess.vue
index 4e09240f878a0eb1fe57c4cfaebcf6121302d6c8..5f272420969687fa6918534e3efd483b23a5a147 100644
--- a/src/views/SignUpSuccess.vue
+++ b/src/views/SignUpSuccess.vue
@@ -6,8 +6,8 @@
     <div class="center">
       <b-container class="msg">
         <p>
-          Un e-mail de confirmation vient d'être envoyé à l'adresse indiquée.<br>
-          Merci de bien vouloir suivre les instructions données afin de finaliser la création de votre compte.
+          {{ $t('signupSuccess.message')[0] }}<br>
+           {{ $t('signupSuccess.message')[1] }}
         </p>
         <!-- <b-button type="button" variant="outline-primary" @click.prevent="$router.push({ name: 'SignIn' })">
           Ouvrir la page de connexion
@@ -15,7 +15,7 @@
       </b-container>
     </div>
     <small class="footer">
-      <p>Propulsé par <a href="https://www.neogeo.fr/" target="_blank" rel="noopener">Neogeo-Technologies</a></p>
+      <p>{{ $t('footer') }} <a href="https://www.neogeo.fr/" target="_blank" rel="noopener">Neogeo-Technologies</a></p>
     </small>
   </div>
 </template>
diff --git a/src/views/TermsOfUse.vue b/src/views/TermsOfUse.vue
index 273df735440f5c372514ff83966e28539f4c5d00..e2a1dc2c3273d3eb8faab173eb8733c99207deb0 100644
--- a/src/views/TermsOfUse.vue
+++ b/src/views/TermsOfUse.vue
@@ -28,7 +28,9 @@
               }) : '' }}<br>
             </div>
             <div v-html="terms ? terms.body : ''"></div>
-            <a v-if="terms && terms.file" :href="terms.file" target="_blank">Télécharger les conditions d'utilisation</a>
+            <a v-if="terms && terms.file" :href="terms.file" target="_blank">
+              {{ $t('termsOfUse.download') }}
+            </a>
           </div>
           <div class="terms-footer">
             <button
@@ -36,14 +38,14 @@
               class="btn btn-primary"
               @click.prevent="acceptTermsOfUse"
             >
-              Accepter
+              {{ $t('words.accept') }}
             </button>
             <button
               type="button"
               class="btn btn-outline-secondary"
               @click="$router.push({ name: 'SignIn' })"
             >
-              Refuser
+              {{ $t('words.decline') }}
             </button>
           </div>
         </b-overlay>
@@ -51,7 +53,7 @@
       <div v-else class="terms-container">
         <b-container class="msg">
           <p>
-            Une erreur est survenue. Veuillez contacter l'administrateur du site.
+            {{ $t('termsOfUse.error') }}
           </p>
         </b-container>
       </div>
diff --git a/src/views/UserProfile.vue b/src/views/UserProfile.vue
index 8894939d8cefa126c61971e918ffb19bde327534..85face7378edd84b5738aa85845af32a0aa20e71 100644
--- a/src/views/UserProfile.vue
+++ b/src/views/UserProfile.vue
@@ -6,7 +6,7 @@
       @click="goBackToNext"
     >
       <b-icon-arrow-bar-left/>
-      Revenir
+      {{ $t('words.goBack') }}
     </b-button>
     <div class="signup-container">
       <div class="signup-header">
@@ -14,11 +14,11 @@
       </div>
       <div class="signup-form">
         <h4 class="title">
-          Compte existant
-          <span class="sub-title">Modifiez les informations relatives à votre compte</span>
+          {{ $t('profile.title') }}
+          <span class="sub-title">{{ $t('profile.subtitle') }}</span>
         </h4>
         <hr class="divider">
-        <ValidationObserver v-slot="{ handleSubmit }">
+        <ValidationObserver ref="form" v-slot="{ handleSubmit }">
           <b-overlay
             :show="loadingUserInformation"
             rounded="lg"
@@ -26,11 +26,11 @@
             variant="white"
           >
             <form>
-              <h5>Vos informations personnelles</h5>
+              <h5>{{ $t('profile.form.personalDetails.title') }}</h5>
               <hr class="divider">
               <div class="row g-2 align-items-center">
                 <div class="col-3">
-                  <label class="col-form-label">Nom d'utilisateur</label>
+                  <label class="col-form-label">{{ $t('words.username') }}</label>
                 </div>
                 <div class="col">
                   <div class="input-group flex-nowrap">
@@ -38,7 +38,7 @@
                       v-model="formUser.username"
                       type="text"
                       class="form-control"
-                      placeholder="Nom d'utilisateur"
+                      :placeholder="$t('words.username')"
                       disabled
                     >
                   </div>
@@ -46,7 +46,7 @@
               </div>
               <div class="row g-2 align-items-center">
                 <div class="col-3">
-                  <label class="col-form-label required">Prénom</label>
+                  <label class="col-form-label required">{{ $t('words.firstname') }}</label>
                 </div>
                 <div class="col">
                   <ValidationProvider ref="first_name" rules="required" v-slot="{ classes, errors }">
@@ -55,7 +55,7 @@
                         v-model="formUser.first_name"
                         type="text"
                         class="form-control"
-                        placeholder="Prénom"
+                        :placeholder="$t('words.firstname')"
                       >
                       <span class="form-errors">{{ errors[0] }}</span>
                     </div>
@@ -64,7 +64,7 @@
               </div>
               <div class="row g-2 align-items-center">
                 <div class="col-3">
-                  <label class="col-form-label required">Nom</label>
+                  <label class="col-form-label required">{{ $t('words.lastname') }}</label>
                 </div>
                 <div class="col">
                   <ValidationProvider ref="last_name" rules="required" v-slot="{ classes, errors }">
@@ -73,7 +73,7 @@
                         v-model="formUser.last_name"
                         type="text"
                         class="form-control"
-                        placeholder="Nom"
+                        :placeholder="$t('words.lastname')"
                       >
                       <span class="form-errors">{{ errors[0] }}</span>
                     </div>
@@ -83,7 +83,7 @@
               <div class="row g-2 align-items-center">
                 <div class="col-3">
                   <label class="col-form-label">
-                    Adresse e-mail
+                    {{ $t('words.email') }}
                   </label>
                 </div>
                 <div class="col">
@@ -93,7 +93,7 @@
                         v-model="formUser.email"
                         type="mail"
                         class="form-control"
-                        placeholder="Adresse e-mail"
+                        :placeholder="$t('words.email')"
                         disabled
                       >
                       <span class="form-errors">{{ errors[0] }}</span>
@@ -103,7 +103,7 @@
               </div>
               <div class="row g-2 align-items-center">
                 <div class="col-3">
-                  <label class="col-form-label">Numéro de téléphone</label>
+                  <label class="col-form-label">{{ $t('words.phone') }}</label>
                 </div>
                 <div class="col">
                   <ValidationProvider ref="phone_number" v-slot="{ classes, errors }">
@@ -121,7 +121,9 @@
               </div>
               <div class="row g-2 align-items-center">
                 <div class="col-3">
-                  <label class="col-form-label">Motif de l'inscription</label>
+                  <label class="col-form-label">
+                    {{  $t('profile.form.personalDetails.reason') }}
+                  </label>
                 </div>
                 <div class="col">
                   <textarea
@@ -132,11 +134,16 @@
               </div>
               <div class="row g-2 align-items-center" style="margin-bottom: 0.5em;">
                 <div class="col-3">
-                  <label class="col-form-label" style="font-size: 0.87em;">Organisation(s)/Groupe(s)</label>
+                  <label
+                    class="col-form-label"
+                    style="font-size: 0.87em;"
+                  >
+                    {{ $t('profile.form.personalDetails.organisation.label') }}
+                  </label>
                 </div>
                 <div v-if="userData" class="col">
                   <div v-if="userData.usergroup_roles.length === 0">
-                    Vous n'êtes rattaché à aucune organisation.
+                    {{ $t('profile.form.personalDetails.organisation.noOrganisation') }}
                   </div>
                   <b-list-group
                     v-else
@@ -147,7 +154,7 @@
                       disabled
                     >
                       <b>{{ usergroup.usergroup.display_name }}</b>
-                      <em> en tant que </em>
+                      <em> {{ $t('as') }} </em>
                       <b>{{ organisationsRoles.find(el => el.choice === usergroup.role).label }}</b>
                     </b-list-group-item>
                   </b-list-group>
@@ -160,7 +167,7 @@
                   <div
                     style="margin: 0 0.5em 0.5em 0.1em; font-size: 0.9em; font-style: italic;"
                   >
-                    Pour toute demande de modification, merci de contacter <a :href="`mailto:${adminMail}`">{{ adminMail }}</a>.
+                    {{ $t('profile.form.personalDetails.organisation.help') }} <a :href="`mailto:${adminMail}`">{{ adminMail }}</a>.
                   </div>
                 </div>
               </div>
@@ -171,7 +178,7 @@
                 @click.prevent="handleSubmit(submitUserInformations)"
                 variant="primary"
               >
-                Valider
+                {{ $t('words.validate') }}
               </b-button>
             </div>
           </b-overlay>
@@ -185,11 +192,16 @@
             :style="'padding: 5px;'"
           >
             <form>
-              <h5>Changer votre adresse e-mail</h5>
+              <h5>{{ $t('profile.form.emailChange.title') }}</h5>
               <hr class="divider">
               <div class="row g-2 align-items-center">
                 <div class="col-3" style="padding-right: 0;">
-                  <label class="col-form-label required" style="font-size: 0.9em;">Nouvelle adresse e-mail</label>
+                  <label
+                    class="col-form-label required"
+                    style="font-size: 0.9em;"
+                  >
+                    {{ $t('profile.form.emailChange.label') }}
+                  </label>
                 </div>
                 <div class="col">
                  <ValidationProvider ref="email" rules="email" v-slot="{ classes, errors }">
@@ -198,7 +210,7 @@
                         v-model="formEmail.new_email"
                         type="mail"
                         class="form-control"
-                        placeholder="Adresse e-mail"
+                        :placeholder="$t('words.email')"
                       >
                       <span class="form-errors">{{ errors[0] }}</span>
                     </div>
@@ -212,8 +224,7 @@
                   <div
                     style="margin: 0 0.5em 0.5em 0.5em; font-size: 0.8em; font-style: italic;"
                   >
-                    Vous pouvez demander le changement de votre adresse mail en renseignant une nouvelle adresse. 
-                    Un lien de confirmation vous sera envoyé sur la nouvelle adresse.
+                    {{ $t('profile.form.emailChange.help') }}
                   </div>
                 </div>
               </div>
@@ -225,7 +236,7 @@
                 @click.prevent="handleSubmit(submitNewEmail)"
                 variant="primary"
               >
-                Valider
+                {{ $t('words.validate') }}
               </b-button>
             </div>
           </b-overlay>
@@ -239,11 +250,13 @@
             :style="'padding: 5px;'"
           >
             <form>
-              <h5>Changer votre mot de passe</h5>
+              <h5>{{ $t('profile.form.passwordChange.title') }}</h5>
               <hr class="divider">
               <div class="row g-2 align-items-center">
                 <div class="col-3" style="padding-right: 0;">
-                  <label class="col-form-label required" style="font-size: 0.9em;">Ancien mot de passe</label>
+                  <label class="col-form-label required" style="font-size: 0.9em;">
+                    {{ $t('profile.form.passwordChange.oldLabel') }}
+                  </label>
                 </div>
                 <div class="col">
                   <ValidationProvider ref="password" rules="required" v-slot="{ classes, errors }">
@@ -253,7 +266,7 @@
                           v-model="formPassword.password"
                           class="form-control"
                           :type="showPassword ? 'text' : 'password'"
-                          placeholder="Ancien mot de passe"
+                          :placeholder="$t('profile.form.passwordChange.oldLabel')"
                         >
                         <span
                           v-if="!showPassword"
@@ -283,7 +296,7 @@
                 <div class="col-3" style="padding-right: 0;">
                   <label
                     class="col-form-label required"
-                    style="font-size: 0.9em;">Nouveau mot de passe</label>
+                    style="font-size: 0.9em;">{{ $t('profile.form.passwordChange.newLabel') }}</label>
                 </div>
                 <div class="col">
                   <ValidationProvider ref="newPassword1" v-slot="{ classes, errors }" vid="confirmation">
@@ -293,7 +306,7 @@
                           v-model="formPassword.newPassword1"
                           :type="showNewPassword2 ? 'text' : 'password'"
                           class="form-control"
-                          placeholder="Nouveau mot de passe"
+                          :placeholder="$t('profile.form.passwordChange.newPlaceholder')"
                         >
                         <span
                           v-if="!showNewPassword2"
@@ -333,7 +346,7 @@
                           v-model="formPassword.newPassword2"
                           class="form-control"
                           :type="showNewPassword2 ? 'text' : 'password'"
-                          placeholder="Confirmez le mot de passe"
+                          :placeholder="$t('profile.form.passwordChange.confirmPlaceholder')"
                         >
                         <span
                           v-if="!showNewPassword2"
@@ -365,10 +378,10 @@
                 <div class="col">
                   <div class="infos">
                     <ul>
-                      <li>Votre mot de passe ne peut pas trop ressembler à vos autres informations personnelles.</li>
-                      <li>Votre mot de passe doit contenir au minimum 8 caractères.</li>
-                      <li>Votre mot de passe ne peut pas être un mot de passe couramment utilisé.</li>
-                      <li>Votre mot de passe ne peut pas être entièrement numérique.</li>
+                      <li>{{ $t('profile.form.passwordChange.passwordHelp')[0] }}</li>
+                      <li>{{ $t('profile.form.passwordChange.passwordHelp')[1] }}</li>
+                      <li>{{ $t('profile.form.passwordChange.passwordHelp')[2] }}</li>
+                      <li>{{ $t('profile.form.passwordChange.passwordHelp')[3] }}</li>
                     </ul>
                   </div>
                 </div>
@@ -381,7 +394,7 @@
                 @click.prevent="handleSubmit(submitNewPassword)"
                 variant="primary"
               >
-                Valider
+                {{ $t('words.validate') }}
               </b-button>
             </div>
           </b-overlay>
@@ -390,7 +403,7 @@
     </div>
     <small class="footer">
       <p>
-        Propulsé par <a href="https://www.neogeo.fr/" target="_blank" rel="noopener">Neogeo-Technologies</a>
+        {{ $t('footer') }} <a href="https://www.neogeo.fr/" target="_blank" rel="noopener">Neogeo-Technologies</a>
       </p>
     </small>
   </div>
@@ -399,6 +412,8 @@
 <script>
 import { mapState, mapMutations, mapActions } from 'vuex';
 
+import i18n from '@/i18n';
+
 import Swal from "sweetalert2";
 import "sweetalert2/dist/sweetalert2.min.css";
 
@@ -413,17 +428,17 @@ import { required, email, confirmed } from 'vee-validate/dist/rules';
 
 extend('required', {
   ...required,
-  message: 'Ce champ est requis',
+  message: () => i18n.t('errors.required')
 });
 
 extend('email', {
   ...email,
-  message: 'Veuillez entrer une adresse e-mail valide',
+  message: () => i18n.t('errors.email'),
 });
 
 extend('confirmed', {
   ...confirmed,
-  message: 'Les mots de passe doivent être identiques',
+  message: () => i18n.t('errors.confirmPassword'),
 });
 
 configure({
@@ -485,6 +500,14 @@ export default {
     }
   },
 
+  watch: {
+    '$i18n.locale': function(newValue, oldValue) {
+      if (newValue !== oldValue) {
+        this.$refs.form.validate();
+      }
+    },
+  },
+
   created() {
     this.SET_NEXT(this.$route.query.next || process.env.VUE_APP_NEXT_DEFAULT);
     if (!this.userData) {
diff --git a/src/views/ValidationEmail.vue b/src/views/ValidationEmail.vue
index bfc8f6482a8201c8aa5f1b8da0033f17710a1aea..df8eba4afe086cedfbe92a22381d5b24dd690952 100644
--- a/src/views/ValidationEmail.vue
+++ b/src/views/ValidationEmail.vue
@@ -6,24 +6,24 @@
     <div class="center">
       <b-container class="msg" v-if="status">
         <p>
-          Votre nouvelle adresse e-mail est validée.
+          {{ $t('validationEmail.message') }}
         </p>
         <b-button
           type="button"
           variant="outline-primary"
           @click.prevent="$router.push({ name: 'SignIn' })"
         >
-          Ouvrir la page de connexion
+          {{ $t('validationEmail.goToLogin') }}
         </b-button>
       </b-container>
       <b-container class="msg" v-else>
         <p>
-          Une erreur est survenue. Veuillez contacter l'administrateur du site.
+          {{ $t('validationEmail.error') }}
         </p>
       </b-container>
     </div>
     <small class="footer">
-      <p>Propulsé par <a href="https://www.neogeo.fr/" target="_blank" rel="noopener">Neogeo-Technologies</a></p>
+      <p>{{ $t('footer') }} <a href="https://www.neogeo.fr/" target="_blank" rel="noopener">Neogeo-Technologies</a></p>
     </small>
   </div>
 </template>
diff --git a/src/views/ValidationRegistration.vue b/src/views/ValidationRegistration.vue
index cfda015bbf795b2d3fbe121f12f020099a5c5778..3cbd4523f3961c457b427bb5c156dcd8a3eaac13 100644
--- a/src/views/ValidationRegistration.vue
+++ b/src/views/ValidationRegistration.vue
@@ -6,10 +6,10 @@
     <div class="center">
       <b-container class="msg" v-if="btnVariant=='success'">
         <p>
-          Merci pour votre inscription.
+          {{ $t('validationRegistration.messages.success')[0] }}
         </p>
         <p>
-          Vous recevrez une notification lors de l'activation de votre compte par l'administrateur de la plateforme.
+          {{ $t('validationRegistration.messages.success')[1] }}
         </p>
         <!-- <b-button type="button" variant="outline-primary" @click.prevent="$router.push({ name: 'SignIn' })">
           Ouvrir la page de connexion
@@ -17,17 +17,17 @@
       </b-container>
       <b-container class="msg" v-else-if="btnVariant=='danger'">
         <p>
-          Une erreur est survenue. Veuillez contacter l'administrateur du site.
+          {{ $t('validationRegistration.messages.error') }}
         </p>
       </b-container>
       <b-container class="msg" v-else>
         <p>
-          Pour confirmer votre inscription <b-button :pressed="btnPressed" :variant="btnVariant" @click.prevent="submit">Cliquez ici</b-button>
+          {{ $t('validationRegistration.confirmation') }} <b-button :pressed="btnPressed" :variant="btnVariant" @click.prevent="submit">{{ $t('validationRegistration.clickHere') }}</b-button>
         </p>
       </b-container>
     </div>
     <small class="footer">
-      <p>Propulsé par <a href="https://www.neogeo.fr/" target="_blank" rel="noopener">Neogeo-Technologies</a></p>
+      <p>{{ $t('footer') }} <a href="https://www.neogeo.fr/" target="_blank" rel="noopener">Neogeo-Technologies</a></p>
     </small>
   </div>
 </template>