diff --git a/package.json b/package.json
index 5718d24d..65255715 100644
--- a/package.json
+++ b/package.json
@@ -63,6 +63,7 @@
     "html-webpack-plugin": "^2.8.1",
     "http-proxy-middleware": "^0.17.2",
     "inject-loader": "^2.0.1",
+    "iso-639-1": "^2.0.3",
     "isparta-loader": "^2.0.0",
     "json-loader": "^0.5.4",
     "karma": "^1.3.0",
diff --git a/src/App.js b/src/App.js
index 39c97a80..a9a46fad 100644
--- a/src/App.js
+++ b/src/App.js
@@ -20,6 +20,10 @@ export default {
   data: () => ({
     mobileActivePanel: 'timeline'
   }),
+  created () {
+    // Load the locale from the storage
+    this.$i18n.locale = this.$store.state.config.interfaceLanguage
+  },
   computed: {
     currentUser () { return this.$store.state.users.currentUser },
     background () {
diff --git a/src/components/interface_language_switcher/interface_language_switcher.vue b/src/components/interface_language_switcher/interface_language_switcher.vue
new file mode 100644
index 00000000..4b541888
--- /dev/null
+++ b/src/components/interface_language_switcher/interface_language_switcher.vue
@@ -0,0 +1,38 @@
+<template>
+  <div>
+    <label for="interface-language-switcher" class='select'>
+      <select id="interface-language-switcher" v-model="language">
+        <option v-for="(langCode, i) in languageCodes" :value="langCode">
+          {{ languageNames[i] }}
+        </option>
+      </select>
+      <i class="icon-down-open"/>
+    </label>
+  </div>
+</template>
+
+<script>
+  import languagesObject from '../../i18n/messages'
+  import ISO6391 from 'iso-639-1'
+  import _ from 'lodash'
+
+  export default {
+    computed: {
+      languageCodes () {
+        return Object.keys(languagesObject)
+      },
+
+      languageNames () {
+        return _.map(this.languageCodes, ISO6391.getName)
+      },
+
+      language: {
+        get: function () { return this.$store.state.config.interfaceLanguage },
+        set: function (val) {
+          this.$store.dispatch('setOption', { name: 'interfaceLanguage', value: val })
+          this.$i18n.locale = val
+        }
+      }
+    }
+  }
+</script>
diff --git a/src/components/settings/settings.js b/src/components/settings/settings.js
index d5ca33cc..f8eaad00 100644
--- a/src/components/settings/settings.js
+++ b/src/components/settings/settings.js
@@ -1,5 +1,6 @@
 /* eslint-env browser */
 import StyleSwitcher from '../style_switcher/style_switcher.vue'
+import InterfaceLanguageSwitcher from '../interface_language_switcher/interface_language_switcher.vue'
 import { filter, trim } from 'lodash'
 
 const settings = {
@@ -28,7 +29,8 @@ const settings = {
     }
   },
   components: {
-    StyleSwitcher
+    StyleSwitcher,
+    InterfaceLanguageSwitcher
   },
   computed: {
     user () {
diff --git a/src/components/settings/settings.vue b/src/components/settings/settings.vue
index 9612876e..f500a1b0 100644
--- a/src/components/settings/settings.vue
+++ b/src/components/settings/settings.vue
@@ -84,6 +84,10 @@
         </li>
       </ul>
     </div>
+    <div class="setting-item">
+      <h2>{{ $t('settings.interfaceLanguage') }}</h2>
+      <interface-language-switcher />
+    </div>
   </div>
 </div>
 </template>
diff --git a/src/i18n/messages.js b/src/i18n/messages.js
index 625ac1b6..30055192 100644
--- a/src/i18n/messages.js
+++ b/src/i18n/messages.js
@@ -350,7 +350,8 @@ const en = {
     default_vis: 'Default visibility scope',
     profile_tab: 'Profile',
     security_tab: 'Security',
-    data_import_export_tab: 'Data Import / Export'
+    data_import_export_tab: 'Data Import / Export',
+    interfaceLanguage: 'Interface language'
   },
   notifications: {
     notifications: 'Notifications',
@@ -1691,7 +1692,8 @@ const ru = {
     profile_tab: 'Профиль',
     security_tab: 'Безопасность',
     data_import_export_tab: 'Импорт / Экспорт данных',
-    collapse_subject: 'Сворачивать посты с темой'
+    collapse_subject: 'Сворачивать посты с темой',
+    interfaceLanguage: 'Язык интерфейса'
   },
   notifications: {
     notifications: 'Уведомления',
diff --git a/src/main.js b/src/main.js
index 87dc49df..37ef49f7 100644
--- a/src/main.js
+++ b/src/main.js
@@ -60,6 +60,7 @@ const persistedStateOptions = {
     'config.loopVideoSilentOnly',
     'config.pauseOnUnfocused',
     'config.stopGifs',
+    'config.interfaceLanguage',
     'users.lastLoginName',
     'statuses.notifications.maxSavedId'
   ]
@@ -79,6 +80,7 @@ const store = new Vuex.Store({
 })
 
 const i18n = new VueI18n({
+  // By default, use the browser locale, we will update it if neccessary
   locale: currentLocale,
   fallbackLocale: 'en',
   messages
@@ -201,4 +203,3 @@ window.fetch('/nodeinfo/2.0.json')
     store.dispatch('setOption', { name: 'suggestionsEnabled', value: suggestions.enabled })
     store.dispatch('setOption', { name: 'suggestionsWeb', value: suggestions.web })
   })
-
diff --git a/src/modules/config.js b/src/modules/config.js
index 45bb1465..ac163316 100644
--- a/src/modules/config.js
+++ b/src/modules/config.js
@@ -1,6 +1,8 @@
 import { set, delete as del } from 'vue'
 import StyleSetter from '../services/style_setter/style_setter.js'
 
+const browserLocale = (window.navigator.language || 'en').split('-')[0]
+
 const defaultState = {
   name: 'Pleroma FE',
   colors: {},
@@ -17,7 +19,8 @@ const defaultState = {
   stopGifs: false,
   replyVisibility: 'all',
   muteWords: [],
-  highlight: {}
+  highlight: {},
+  interfaceLanguage: browserLocale
 }
 
 const config = {
diff --git a/yarn.lock b/yarn.lock
index 390ad70b..2be9efc8 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3081,6 +3081,10 @@ isexe@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
 
+iso-639-1@^2.0.3:
+  version "2.0.3"
+  resolved "https://registry.yarnpkg.com/iso-639-1/-/iso-639-1-2.0.3.tgz#72dd3448ac5629c271628c5ac566369428d6ccd0"
+
 isobject@^2.0.0:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89"