diff --git a/www/js/app.js b/www/js/app.js
index bfe47746f3abb2584fa11bb4dee1647311c5a9b1..b6e9fdf0cdd65e81b5be99df51eb26c730cab458 100644
--- a/www/js/app.js
+++ b/www/js/app.js
@@ -407,29 +407,9 @@ angular.module('cesium', ['ionic', 'ionic-material', 'ngMessages', 'pascalprecht
       }
     });
 
-  var onLanguageChange = function() {
-    var lang = $translate.use();
-    console.debug('[app] Locale ['+lang+']');
-
-    // config moment lib
-    try {
-      moment.locale(lang.substr(0,2));
-    }
-    catch(err) {
-      moment.locale('en');
-      console.warn('[app] Unknown local for moment lib. Using default [en]');
-    }
-
-    // config numeral lib
-    try {
-      numeral.language(lang.substr(0,2));
-    }
-    catch(err) {
-      numeral.language('en');
-      console.warn('[app] Unknown local for numeral lib. Using default [en]');
-    }
-
-    // Set some translation need by filters
+  // Update some translations, when locale changed
+  function onLocaleChange() {
+    console.debug('[app] Loading cached translations for locale [{0}]'.format($translate.use()));
     $translate(['COMMON.DATE_PATTERN', 'COMMON.DATE_SHORT_PATTERN', 'COMMON.UD'])
       .then(function(translations) {
         $rootScope.translations = $rootScope.translations || {};
@@ -446,17 +426,14 @@ angular.module('cesium', ['ionic', 'ionic-material', 'ngMessages', 'pascalprecht
           $rootScope.translations.UD = 'UD';
         }
       });
-
-  };
-
-  // Set up moment translation
-  $rootScope.$on('$translateChangeSuccess', onLanguageChange);
+  }
+  csSettings.api.locale.on.changed($rootScope, onLocaleChange, this);
 
   // start plugin
   PluginService.start();
 
-  // set locale to vendor lib
-  onLanguageChange();
+  // Force at least on call
+  onLocaleChange();
 })
 ;
 
diff --git a/www/js/controllers/settings-controllers.js b/www/js/controllers/settings-controllers.js
index e13027a2239b8a21c481ac55ec4ec0a0b2941983..85291c56b98e544b53a82f70da1b735f19f2326f 100644
--- a/www/js/controllers/settings-controllers.js
+++ b/www/js/controllers/settings-controllers.js
@@ -43,12 +43,14 @@ function SettingsController($scope, $q, $ionicPopup, $timeout, $translate, csHtt
 
     // Fill locales
     $scope.locales = angular.copy(csSettings.locales);
-    var locale = _.findWhere($scope.locales, {id: csSettings.defaultSettings.locale.id});
+
+    // Apply settings
     angular.merge($scope.formData, csSettings.data);
-    $scope.formData.locale = locale;
-    if (csSettings.data.locale && csSettings.data.locale.id) {
-      $scope.formData.locale = _.findWhere($scope.locales, {id: csSettings.data.locale.id});
-    }
+
+    // Make sure to use full locale object (id+name)
+    $scope.formData.locale = (csSettings.data.locale && csSettings.data.locale.id && _.findWhere($scope.locales, {id: csSettings.data.locale.id})) ||
+      _.findWhere($scope.locales, {id: csSettings.defaultSettings.locale.id});
+
     $scope.loading = false;
 
     $timeout(function() {
@@ -63,9 +65,12 @@ function SettingsController($scope, $q, $ionicPopup, $timeout, $translate, csHtt
       $scope.actionsPopover.hide();
     }
     $scope.pendingSaving = true;
-    csSettings.reset();
-    angular.merge($scope.formData, csSettings.data);
-    $scope.pendingSaving = false;
+    csSettings.reset()
+      .then(function() {
+        // reload
+        $scope.load();
+        $scope.pendingSaving = false;
+      });
   };
 
   $scope.changeLanguage = function(langKey) {
diff --git a/www/js/services/settings-services.js b/www/js/services/settings-services.js
index 53dca121e713343731af846b91ee184f70bc704a..996d1a148ed15584cd883e7038977af8d0591c8a 100644
--- a/www/js/services/settings-services.js
+++ b/www/js/services/settings-services.js
@@ -1,7 +1,7 @@
 
 angular.module('cesium.settings.services', ['ngResource', 'ngApi', 'cesium.config', 'cesium.device.services'])
 
-.factory('csSettings', function($q, Api, localStorage, $translate, csConfig, Device) {
+.factory('csSettings', function($rootScope, $q, Api, localStorage, $translate, csConfig, Device) {
   'ngInject';
 
     function Factory() {
@@ -30,13 +30,22 @@ angular.module('cesium.settings.services', ['ngResource', 'ngApi', 'cesium.confi
 
         // If another locale exists with the same root: use it
         var similarLocale = _.find(locales, function(l) {
-          return String.prototype.startsWith.call(l, locale);
+          return String.prototype.startsWith.call(l.id, locale);
         });
-        if (similarLocale) return similarLocale;
+        if (similarLocale) return similarLocale.id;
 
         return fallbackLocale;
       }
 
+      // Convert browser locale to app locale (fix #140)
+      function fixLocaleWithLog (locale) {
+        var fixedLocale = fixLocale(locale);
+        if (locale != fixedLocale) {
+          console.debug('[settings] Fix locale [{0}] -> [{1}]'.format(locale, fixedLocale));
+        }
+        return fixedLocale;
+      }
+
       var
       constants = {
         STORAGE_KEY: 'CESIUM_SETTINGS'
@@ -77,11 +86,11 @@ angular.module('cesium.settings.services', ['ngResource', 'ngApi', 'cesium.confi
           notificationReadTime: 0
         },
         locale: {
-          id: fixLocale(csConfig.defaultLanguage || $translate.use()) // use config locale if set, or browser default
+          id: fixLocaleWithLog(csConfig.defaultLanguage || $translate.use()) // use config locale if set, or browser default
         }
       }, csConfig),
 
-      data = angular.copy(defaultSettings),
+      data = {},
       previousData,
 
       api = new Api(this, "csSettings"),
@@ -90,8 +99,10 @@ angular.module('cesium.settings.services', ['ngResource', 'ngApi', 'cesium.confi
         _.keys(data).forEach(function(key){
           delete data[key];
         });
-        angular.merge(data, defaultSettings);
-        api.data.raisePromise.reset(data)
+
+        applyData(defaultSettings);
+
+        return api.data.raisePromise.reset(data)
           .then(store);
       },
 
@@ -129,7 +140,32 @@ angular.module('cesium.settings.services', ['ngResource', 'ngApi', 'cesium.confi
           .then(emitChangedEvent);
       },
 
-      restore = function(first) {
+      applyData = function(newData) {
+        var localeChanged = false;
+        if (newData.locale && newData.locale.id) {
+          // Fix previously stored locale (could use bad format)
+          newData.locale.id = fixLocale(newData.locale.id);
+          localeChanged = !data.locale || newData.locale.id !== data.locale.id || newData.locale.id !== $translate.use();
+        }
+
+        // Apply stored settings
+        angular.merge(data, newData);
+
+        // Always force the usage of deffault settings
+        // This is a workaround for DEV (TODO: implement edition in settings ?)
+        data.timeWarningExpire = defaultSettings.timeWarningExpire;
+        data.timeWarningExpireMembership = defaultSettings.timeWarningExpireMembership;
+        data.cacheTimeMs = defaultSettings.cacheTimeMs;
+        data.timeout = defaultSettings.timeout;
+
+        // Apply the new locale (only if need)
+        if (localeChanged) {
+          $translate.use(fixLocale(data.locale.id)); // will produce an event cached by onLocaleChange();
+        }
+
+      },
+
+      restore = function() {
         var now = new Date().getTime();
         return $q(function(resolve, reject){
           console.debug("[settings] Loading from local storage...");
@@ -142,12 +178,9 @@ angular.module('cesium.settings.services', ['ngResource', 'ngApi', 'cesium.confi
 
           // No settings stored
           if (!storedData) {
-            console.debug("[settings] No settings in local storage");
-            if (data.locale.id !== $translate.use()) {
-              console.debug("[settings] Changing locale to [{0}]...".format(data.locale.id));
-              $translate.use(data.locale.id);
-              finishRestore();
-            }
+            console.debug("[settings] No settings in local storage. Using defaults.");
+            applyData(defaultSettings);
+            finishRestore();
             return;
           }
 
@@ -176,37 +209,48 @@ angular.module('cesium.settings.services', ['ngResource', 'ngApi', 'cesium.confi
             delete storedData.DUNITER_NODE_ES;
           }
 
-          var localeChanged = false;
-          if (storedData.locale && storedData.locale.id) {
-            // Fix previously stored bad locale
-            storedData.locale.id = fixLocale(storedData.locale.id);
-            localeChanged = (storedData.locale.id !== data.locale.id || storedData.locale.id !== $translate.use());
-          }
-
-          // Apply stored settings
-          angular.merge(data, storedData);
-
-          // Always force the usage of deffault settings
-          // This is a workaround for DEV (TODO: implement edition in settings ?)
-          data.timeWarningExpire = defaultSettings.timeWarningExpire;
-          data.timeWarningExpireMembership = defaultSettings.timeWarningExpireMembership;
-          data.cacheTimeMs = defaultSettings.cacheTimeMs;
-          data.timeout = defaultSettings.timeout;
-
-          // Apply the new locale (only if need)
-          if (localeChanged) {
-            $translate.use(fixLocale(data.locale.id));
-          }
+          // Apply stored data
+          applyData(storedData);
 
           console.debug('[settings] Loaded from local storage in '+(new Date().getTime()-now)+'ms');
           finishRestore();
         });
+      },
+
+        // Detect locale sucessuf changes, then apply to vendor libs
+      onLocaleChange = function() {
+        var locale = $translate.use();
+        console.debug('[settings] Locale ['+locale+']');
+
+        // config moment lib
+        try {
+          moment.locale(locale.substr(0,2));
+        }
+        catch(err) {
+          moment.locale('en');
+          console.warn('[settings] Unknown local for moment lib. Using default [en]');
+        }
+
+        // config numeral lib
+        try {
+          numeral.language(locale.substr(0,2));
+        }
+        catch(err) {
+          numeral.language('en');
+          console.warn('[settings] Unknown local for numeral lib. Using default [en]');
+        }
+
+        // Emit event
+        api.locale.raise.changed(locale);
       };
+      $rootScope.$on('$translateChangeSuccess', onLocaleChange);
+
 
     api.registerEvent('data', 'reset');
     api.registerEvent('data', 'changed');
     api.registerEvent('data', 'store');
     api.registerEvent('data', 'ready');
+    api.registerEvent('locale', 'changed');
 
     return {
       data: data,