diff --git a/src/components/error_window/error_window.vue b/src/components/async_component_error/async_component_error.vue
similarity index 51%
rename from src/components/error_window/error_window.vue
rename to src/components/async_component_error/async_component_error.vue
index ddb4ba00..66b3fb53 100644
--- a/src/components/error_window/error_window.vue
+++ b/src/components/async_component_error/async_component_error.vue
@@ -1,19 +1,17 @@
 <template>
-  <div class="error-window panel">
-    <div class="panel-heading">
-      <span class="title">
+  <div class="async-component-error">
+    <div>
+      <h4>
         {{ $t('general.generic_error') }}
-      </span>
-    </div>
-    <div class="panel-body">
+      </h4>
       <p>
         {{ $t('general.error_retry') }}
       </p>
       <button
         class="btn"
-        @click="closeAllModals"
-      >
-        {{ $t('general.close') }}
+        @click="retry"
+        >
+        {{ $t('general.retry') }}
       </button>
     </div>
   </div>
@@ -22,9 +20,7 @@
 <script>
 export default {
   methods: {
-    closeAllModals () {
-      // TODO make a global hook to close all modals?
-      this.$store.dispatch('closeSettingsModal')
+    retry () {
       this.$emit('resetAsyncComponent')
     }
   }
@@ -32,7 +28,11 @@ export default {
 </script>
 
 <style lang="scss">
-.error-window {
+.async-component-error {
+  display: flex;
+  height: 100%;
+  align-items: center;
+  justify-content: center;
   .btn {
     margin: .5em;
     padding: .5em 2em;
diff --git a/src/components/big_spinner/big_spinner.vue b/src/components/big_spinner/big_spinner.vue
deleted file mode 100644
index 64f16e4d..00000000
--- a/src/components/big_spinner/big_spinner.vue
+++ /dev/null
@@ -1,16 +0,0 @@
-<template>
-  <div class="big-spinner">
-    <i class="icon-spin4 animate-spin" />
-  </div>
-</template>
-
-<style lang="scss">
-.big-spinner {
-  font-size: 15em;
-  line-height: 0;
-  opacity: .6;
-  > i {
-    color: white;
-  }
-}
-</style>
diff --git a/src/components/panel_loading/panel_loading.vue b/src/components/panel_loading/panel_loading.vue
new file mode 100644
index 00000000..4efebb3c
--- /dev/null
+++ b/src/components/panel_loading/panel_loading.vue
@@ -0,0 +1,29 @@
+<template>
+  <div class="panel-loading">
+    <span class="loading-text">
+      <i class="icon-spin4 animate-spin" />
+      {{ $t('general.loading') }}
+    </span>
+  </div>
+</template>
+
+<style lang="scss">
+@import 'src/_variables.scss';
+
+.panel-loading {
+  display: flex;
+  height: 100%;
+  align-items: center;
+  justify-content: center;
+  font-size: 2em;
+  color: $fallback--text;
+  color: var(--text, $fallback--text);
+  .loading-text i {
+    font-size: 3em;
+    line-height: 0;
+    vertical-align: middle;
+    color: $fallback--text;
+    color: var(--text, $fallback--text);
+  }
+}
+</style>
diff --git a/src/components/settings_modal/settings_modal.js b/src/components/settings_modal/settings_modal.js
index 84d673a8..32ef38d6 100644
--- a/src/components/settings_modal/settings_modal.js
+++ b/src/components/settings_modal/settings_modal.js
@@ -1,6 +1,6 @@
 import Modal from 'src/components/modal/modal.vue'
-import BigSpinner from 'src/components/big_spinner/big_spinner.vue'
-import ErrorWindow from 'src/components/error_window/error_window.vue'
+import PanelLoading from 'src/components/panel_loading/panel_loading.vue'
+import AsyncComponentError from 'src/components/async_component_error/async_component_error.vue'
 import getResettableAsyncComponent from 'src/services/resettable_async_component.js'
 
 const SettingsModal = {
@@ -9,12 +9,20 @@ const SettingsModal = {
     SettingsModalContent: getResettableAsyncComponent(
       () => import('./settings_modal_content.vue'),
       {
-        loading: BigSpinner,
-        error: ErrorWindow,
+        loading: PanelLoading,
+        error: AsyncComponentError,
         delay: 0
       }
     )
   },
+  methods: {
+    closeModal () {
+      this.$store.dispatch('closeSettingsModal')
+    },
+    peekModal () {
+      this.$store.dispatch('togglePeekSettingsModal')
+    }
+  },
   computed: {
     modalActivated () {
       return this.$store.state.interface.settingsModalState !== 'hidden'
diff --git a/src/components/settings_modal/settings_modal.scss b/src/components/settings_modal/settings_modal.scss
index ece96364..833ff89a 100644
--- a/src/components/settings_modal/settings_modal.scss
+++ b/src/components/settings_modal/settings_modal.scss
@@ -3,7 +3,7 @@
   overflow: hidden;
 
   &.peek {
-    .modal-panel {
+    .settings-modal-panel {
       /* Explanation:
        * Modal is positioned vertically centered.
        * 100vh - 100% = Distance between modal's top+bottom boundaries and screen
@@ -15,4 +15,30 @@
       transform: translateY(calc(((100vh - 100%) / 2 + 100%) - 50px));
     }
   }
+
+  .settings-modal-panel {
+    overflow: hidden;
+    transition: transform;
+    transition-timing-function: ease-in-out;
+    transition-duration: 300ms;
+    width: 1000px;
+    max-width: 90vw;
+    height: 90vh;
+
+    @media all and (max-width: 800px) {
+      max-width: 100vw;
+      height: 100vh;
+    }
+
+    .panel-body {
+      height: 100%;
+      overflow-y: hidden;
+
+      .btn {
+        min-height: 28px;
+        min-width: 10em;
+        padding: 0 2em;
+      }
+    }
+  }
 }
diff --git a/src/components/settings_modal/settings_modal.vue b/src/components/settings_modal/settings_modal.vue
index b6ca5c6b..ded02f4a 100644
--- a/src/components/settings_modal/settings_modal.vue
+++ b/src/components/settings_modal/settings_modal.vue
@@ -5,10 +5,47 @@
     :class="{ peek: modalPeeked }"
     :no-background="modalPeeked"
   >
-    <SettingsModalContent
-      v-if="modalActivated"
-      class="modal-panel"
-    />
+    <div class="settings-modal-panel panel">
+      <div class="panel-heading">
+        <span class="title">
+          {{ $t('settings.settings') }}
+        </span>
+        <transition name="fade">
+          <template v-if="currentSaveStateNotice">
+            <div
+              v-if="currentSaveStateNotice.error"
+              class="alert error"
+              @click.prevent
+            >
+              {{ $t('settings.saving_err') }}
+            </div>
+
+            <div
+              v-if="!currentSaveStateNotice.error"
+              class="alert transparent"
+              @click.prevent
+            >
+              {{ $t('settings.saving_ok') }}
+            </div>
+          </template>
+        </transition>
+        <button
+          class="btn"
+          @click="peekModal"
+        >
+          {{ $t('general.peek') }}
+        </button>
+        <button
+          class="btn"
+          @click="closeModal"
+        >
+          {{ $t('general.close') }}
+        </button>
+      </div>
+      <div class="panel-body">
+        <SettingsModalContent v-if="modalActivated" />
+      </div>
+    </div>
   </Modal>
 </template>
 
diff --git a/src/components/settings_modal/settings_modal_content.js b/src/components/settings_modal/settings_modal_content.js
index b842ec7d..b27fbd28 100644
--- a/src/components/settings_modal/settings_modal_content.js
+++ b/src/components/settings_modal/settings_modal_content.js
@@ -31,14 +31,6 @@ const SettingsModalContent = {
     isLoggedIn () {
       return !!this.$store.state.users.currentUser
     }
-  },
-  methods: {
-    closeModal () {
-      this.$store.dispatch('closeSettingsModal')
-    },
-    peekModal () {
-      this.$store.dispatch('togglePeekSettingsModal')
-    }
   }
 }
 
diff --git a/src/components/settings_modal/settings_modal_content.scss b/src/components/settings_modal/settings_modal_content.scss
index 92e167a2..f80306c6 100644
--- a/src/components/settings_modal/settings_modal_content.scss
+++ b/src/components/settings_modal/settings_modal_content.scss
@@ -1,32 +1,6 @@
 @import 'src/_variables.scss';
-
-.settings-modal-panel {
-  overflow: hidden;
-  transition: transform;
-  transition-timing-function: ease-in-out;
-  transition-duration: 300ms;
-  width: 1000px;
-  max-width: 90vw;
-  height: 90vh;
-
-  @media all and (max-width: 800px) {
-    max-width: 100vw;
-    height: 100vh;
-  }
-
-  .settings_tab-switcher {
-    height: 100%;
-  }
-  .panel-body {
-    height: 100%;
-    overflow-y: hidden;
-
-    .btn {
-      min-height: 28px;
-      min-width: 10em;
-      padding: 0 2em;
-    }
-  }
+.settings_tab-switcher {
+  height: 100%;
 
   .full-height {
     height: 100%;
diff --git a/src/components/settings_modal/settings_modal_content.vue b/src/components/settings_modal/settings_modal_content.vue
index 865a2adf..3e06148f 100644
--- a/src/components/settings_modal/settings_modal_content.vue
+++ b/src/components/settings_modal/settings_modal_content.vue
@@ -1,112 +1,72 @@
 <template>
-  <div class="settings-modal-panel panel">
-    <div class="panel-heading">
-      <span class="title">
-        {{ $t('settings.settings') }}
-      </span>
-      <transition name="fade">
-        <template v-if="currentSaveStateNotice">
-          <div
-            v-if="currentSaveStateNotice.error"
-            class="alert error"
-            @click.prevent
-          >
-            {{ $t('settings.saving_err') }}
-          </div>
-
-          <div
-            v-if="!currentSaveStateNotice.error"
-            class="alert transparent"
-            @click.prevent
-          >
-            {{ $t('settings.saving_ok') }}
-          </div>
-        </template>
-      </transition>
-      <button
-        class="btn"
-        @click="peekModal"
+  <tab-switcher
+    ref="tabSwitcher"
+    class="settings_tab-switcher"
+    :side-tab-bar="true"
+    :scrollable-tabs="true"
+    >
+    <div
+      :label="$t('settings.general')"
+      icon="wrench"
       >
-        {{ $t('general.peek') }}
-      </button>
-      <button
-        class="btn"
-        @click="closeModal"
-      >
-        {{ $t('general.close') }}
-      </button>
+      <GeneralTab />
     </div>
-    <div class="panel-body">
-      <tab-switcher
-        ref="tabSwitcher"
-        class="settings_tab-switcher"
-        :side-tab-bar="true"
-        :scrollable-tabs="true"
+    <div
+      v-if="isLoggedIn"
+      :label="$t('settings.profile_tab')"
+      icon="user"
       >
-        <div
-          :label="$t('settings.general')"
-          icon="wrench"
-        >
-          <GeneralTab />
-        </div>
-        <div
-          v-if="isLoggedIn"
-          :label="$t('settings.profile_tab')"
-          icon="user"
-        >
-          <ProfileTab />
-        </div>
-        <div
-          v-if="isLoggedIn"
-          :label="$t('settings.security_tab')"
-          icon="lock"
-        >
-          <SecurityTab />
-        </div>
-        <div
-          :label="$t('settings.filtering')"
-          icon="filter"
-        >
-          <FilteringTab />
-        </div>
-        <div
-          :label="$t('settings.theme')"
-          icon="brush"
-        >
-          <ThemeTab />
-        </div>
-        <div
-          v-if="isLoggedIn"
-          :label="$t('settings.notifications')"
-          icon="chat"
-        >
-          <NotificationsTab />
-        </div>
-        <div
-          v-if="isLoggedIn"
-          :label="$t('settings.data_import_export_tab')"
-          icon="download"
-        >
-          <DataImportExportTab />
-        </div>
-        <div
-          v-if="isLoggedIn"
-          :label="$t('settings.mutes_and_blocks')"
-          :fullHeight="true"
-          class="full-height"
-          icon="eye-off"
-        >
-          <MutesAndBlocksTab />
-        </div>
-        <div
-          :label="$t('settings.version.title')"
-          icon="info-circled"
-        >
-          <VersionTab />
-        </div>
-      </tab-switcher>
+      <ProfileTab />
     </div>
-  </div>
+    <div
+      v-if="isLoggedIn"
+      :label="$t('settings.security_tab')"
+      icon="lock"
+      >
+      <SecurityTab />
+    </div>
+    <div
+      :label="$t('settings.filtering')"
+      icon="filter"
+      >
+      <FilteringTab />
+    </div>
+    <div
+      :label="$t('settings.theme')"
+      icon="brush"
+      >
+      <ThemeTab />
+    </div>
+    <div
+      v-if="isLoggedIn"
+      :label="$t('settings.notifications')"
+      icon="chat"
+      >
+      <NotificationsTab />
+    </div>
+    <div
+      v-if="isLoggedIn"
+      :label="$t('settings.data_import_export_tab')"
+      icon="download"
+      >
+      <DataImportExportTab />
+    </div>
+    <div
+      v-if="isLoggedIn"
+      :label="$t('settings.mutes_and_blocks')"
+      :fullHeight="true"
+      class="full-height"
+      icon="eye-off"
+      >
+      <MutesAndBlocksTab />
+    </div>
+    <div
+      :label="$t('settings.version.title')"
+      icon="info-circled"
+      >
+      <VersionTab />
+    </div>
+  </tab-switcher>
 </template>
 
 <script src="./settings_modal_content.js"></script>
diff --git a/src/i18n/en.json b/src/i18n/en.json
index e3dc75d7..062af2c7 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -59,8 +59,10 @@
     "apply": "Apply",
     "submit": "Submit",
     "more": "More",
+    "loading": "Loading…",
     "generic_error": "An error occured",
     "error_retry": "Please try again",
+    "retry": "Try again",
     "optional": "optional",
     "show_more": "Show more",
     "show_less": "Show less",