diff --git a/app.js b/app.js
index ecc0c79a39df1bc454d682582167e2a535db6000..915f6767056306ae5bcabcbcfc02118b51f9ac8a 100644
--- a/app.js
+++ b/app.js
@@ -17,7 +17,8 @@ require.config({
     'd3': '../node_modules/d3/d3.min',
     'virtual-dom': '../node_modules/virtual-dom/dist/virtual-dom',
     'rbush': '../node_modules/rbush/rbush',
-    'helper': 'utils/helper'
+    'helper': 'utils/helper',
+    'language': 'utils/language'
   },
   shim: {
     'leaflet.label': ['leaflet'],
diff --git a/lib/gui.js b/lib/gui.js
index 9802d86abf4f481f107f243e5821698dbc82bde3..3f8924515d11e53dc3b69de9729df1faed7dbd7b 100644
--- a/lib/gui.js
+++ b/lib/gui.js
@@ -7,7 +7,7 @@ define(['chroma-js', 'map', 'sidebar', 'tabs', 'container', 'legend',
             Title, About, DataDistributor, FilterGUI, HostnameFilter) {
     'use strict';
 
-    return function (config, router) {
+    return function (config, router, language) {
       var self = this;
       var content;
       var contentDiv;
@@ -81,7 +81,7 @@ define(['chroma-js', 'map', 'sidebar', 'tabs', 'container', 'legend',
       var infobox = new Infobox(config, sidebar, router);
       var tabs = new Tabs();
       var overview = new Container();
-      var legend = new Legend(config);
+      var legend = new Legend(config, language);
       var newnodeslist = new SimpleNodelist('new', 'firstseen', router, _.t('node.new'));
       var lostnodeslist = new SimpleNodelist('lost', 'lastseen', router, _.t('node.missing'));
       var nodelist = new Nodelist(router);
diff --git a/lib/legend.js b/lib/legend.js
index d97b3387cad2486eacee19b61ec9a2a4dbe30a44..fca8a4f2839eea234fcadb652b3bc48b09018ffd 100644
--- a/lib/legend.js
+++ b/lib/legend.js
@@ -1,7 +1,7 @@
 define(['helper'], function (helper) {
   'use strict';
 
-  return function (config) {
+  return function (config, language) {
     var self = this;
     var stats = document.createTextNode('');
     var timestamp = document.createTextNode('');
@@ -28,6 +28,8 @@ define(['helper'], function (helper) {
       h2.textContent = config.siteName;
       el.appendChild(h2);
 
+      language.languageSelect(el);
+
       var p = document.createElement('p');
       p.classList.add('legend');
       p.innerHTML = '<span class="legend-new"><span class="symbol"></span> ' + _.t('sidebar.nodeNew') + '</span>' +
diff --git a/lib/main.js b/lib/main.js
index 0324adedd627c3747b792a8c24f08e742ebc235b..10bca3da09e2bbf6f89d7f00b6bedc038c7c2cdd 100644
--- a/lib/main.js
+++ b/lib/main.js
@@ -1,5 +1,5 @@
-define(['polyglot', 'moment', 'router', 'leaflet', 'gui', 'helper'],
-  function (Polyglot, moment, Router, L, GUI, helper) {
+define(['polyglot', 'moment', 'router', 'leaflet', 'gui', 'helper', 'language'],
+  function (Polyglot, moment, Router, L, GUI, helper, Language) {
     'use strict';
 
     return function (config) {
@@ -150,35 +150,7 @@ define(['polyglot', 'moment', 'router', 'leaflet', 'gui', 'helper'],
         };
       }
 
-      function setTranslation(json) {
-        _.extend(json);
-
-        moment.locale(_.locale(), {
-          longDateFormat: {
-            LT: 'HH:mm',
-            LTS: 'HH:mm:ss',
-            L: 'DD.MM.YYYY',
-            LL: 'D. MMMM YYYY',
-            LLL: 'D. MMMM YYYY HH:mm',
-            LLLL: 'dddd, D. MMMM YYYY HH:mm'
-          },
-          calendar: json.momentjs.calendar,
-          relativeTime: json.momentjs.relativeTime
-        });
-      }
-
-      var language = navigator.languages && navigator.languages[0] || navigator.language || navigator.userLanguage;
-      var locale = config.supportedLocale[0];
-      config.supportedLocale.some(function (item) {
-        if (language.indexOf(item) !== -1) {
-          locale = item;
-          return true;
-        }
-        return false;
-      });
-
-      window._ = new Polyglot({ locale: locale, allowMissing: true });
-      helper.getJSON('locale/' + _.locale() + '.json?' + config.cacheBreaker).then(setTranslation);
+      var language = new Language(config);
 
       var router = new Router();
 
@@ -200,7 +172,7 @@ define(['polyglot', 'moment', 'router', 'leaflet', 'gui', 'helper'],
 
       update()
         .then(function (d) {
-          var gui = new GUI(config, router);
+          var gui = new GUI(config, router, language);
           gui.setData(d);
           router.setData(d);
           router.start();
diff --git a/lib/utils/language.js b/lib/utils/language.js
new file mode 100644
index 0000000000000000000000000000000000000000..91b374791b2074564006ca510aee81f75e9ea097
--- /dev/null
+++ b/lib/utils/language.js
@@ -0,0 +1,59 @@
+define(['polyglot', 'moment', 'helper'], function (Polyglot, moment, helper) {
+  'use strict';
+  return function (config) {
+    function languageSelect(el) {
+      var select = document.createElement('select');
+      select.className = 'language-switch';
+      select.addEventListener('change', setLocale);
+      el.appendChild(select);
+
+      // Keep english
+      select.innerHTML = '<option>Language</option>';
+      for (var i = 0; i < config.supportedLocale.length; i++) {
+        select.innerHTML += '<option value="' + config.supportedLocale[i] + '">' + config.supportedLocale[i] + '</option>';
+      }
+    }
+
+    function setLocale(event) {
+      localStorage.setItem('language', getLocale(event.target.value));
+      location.reload();
+    }
+
+    function getLocale(input) {
+      var language = input || localStorage.getItem('language') || navigator.languages && navigator.languages[0] || navigator.language || navigator.userLanguage;
+      var locale = config.supportedLocale[0];
+      config.supportedLocale.some(function (item) {
+        if (language.indexOf(item) !== -1) {
+          locale = item;
+          return true;
+        }
+        return false;
+      });
+      return locale;
+    }
+
+    function setTranslation(json) {
+      _.extend(json);
+
+      moment.locale(_.locale(), {
+        longDateFormat: {
+          LT: 'HH:mm',
+          LTS: 'HH:mm:ss',
+          L: 'DD.MM.YYYY',
+          LL: 'D. MMMM YYYY',
+          LLL: 'D. MMMM YYYY HH:mm',
+          LLLL: 'dddd, D. MMMM YYYY HH:mm'
+        },
+        calendar: json.momentjs.calendar,
+        relativeTime: json.momentjs.relativeTime
+      });
+    }
+
+    window._ = new Polyglot({ locale: getLocale(), allowMissing: true });
+    helper.getJSON('locale/' + _.locale() + '.json?' + config.cacheBreaker).then(setTranslation);
+
+    return {
+      languageSelect: languageSelect
+    };
+  };
+});
diff --git a/scss/modules/_legend.scss b/scss/modules/_legend.scss
index 965848dbe9749348e98e06b70c937e3153fd114d..50e96c116a5b738aa71dfef15361afeb8f4aa80e 100644
--- a/scss/modules/_legend.scss
+++ b/scss/modules/_legend.scss
@@ -1,3 +1,21 @@
+header {
+  h2 {
+    display: inline-block;
+  }
+}
+
+.language-switch {
+  background: transparent;
+  border: 0;
+  color: $color-black;
+  float: right;
+  margin: 20px 16px 0 0;
+
+  option {
+    background: $color-white;
+  }
+}
+
 .legend {
   .symbol {
     border-radius: 50%;
diff --git a/scss/night.scss b/scss/night.scss
index 304a31ffe9c7c9a546269a5b527aadae3cd7f99c..4e37f2f3bb81d0f92c7b700cfb2656df002e9b4f 100644
--- a/scss/night.scss
+++ b/scss/night.scss
@@ -35,6 +35,14 @@ html {
     }
   }
 
+  .language-switch {
+    color: $color-black;
+
+    option {
+      background: $color-white;
+    }
+  }
+
   //@import 'modules/filter';
   .filter-node {
     input {