diff --git a/aleksis/core/frontend/components/app/App.vue b/aleksis/core/frontend/components/app/App.vue
index 554def4e849e3ed455692ba009cb90934149f287..5ad7fceeff0dc89ba5ec67e927f9bc92d6ac31d1 100644
--- a/aleksis/core/frontend/components/app/App.vue
+++ b/aleksis/core/frontend/components/app/App.vue
@@ -86,7 +86,7 @@
           </div>
 
           <error-page
-            v-if="error404 && !$root.contentLoading"
+            v-if="error404"
             short-error-message-key="network_errors.error_404"
             long-error-message-key="network_errors.page_not_found"
             redirect-button-text-key="network_errors.back_to_start"
@@ -230,6 +230,7 @@ import useRegisterSWMixin from "../../mixins/useRegisterSW";
 import offlineMixin from "../../mixins/offline";
 import menusMixin from "../../mixins/menus";
 import routesMixin from "../../mixins/routes";
+import error404Mixin from "../../mixins/error404";
 
 export default {
   data() {
@@ -282,11 +283,6 @@ export default {
     },
     $route: {
       handler(newRoute) {
-        if (newRoute.matched.length === 0 || newRoute.meta.hide) {
-          this.error404 = true;
-        } else {
-          this.error404 = false;
-        }
         this.$apollo.queries.messages.refetch();
       },
       immediate: true,
@@ -302,7 +298,7 @@ export default {
     SideNav,
     SnackbarItem,
   },
-  mixins: [useRegisterSWMixin, offlineMixin, menusMixin, routesMixin],
+  mixins: [useRegisterSWMixin, offlineMixin, menusMixin, routesMixin, error404Mixin],
 };
 </script>
 
diff --git a/aleksis/core/frontend/mixins/error404.js b/aleksis/core/frontend/mixins/error404.js
new file mode 100644
index 0000000000000000000000000000000000000000..d66f47d0cf274dcae76c0fc68a3d2b203b90efa0
--- /dev/null
+++ b/aleksis/core/frontend/mixins/error404.js
@@ -0,0 +1,26 @@
+/**
+ * Vue mixin containing code setting error 404 status.
+ *
+ * Only used by main App component, but factored out for readability.
+ */
+
+const error404Mixin = {
+  methods: {
+    set404() {
+      if (this.$route.matched.length === 0) {
+        this.error404 = true;
+        this.$root.contentLoading = false;
+      } else {
+        this.error404 = false;
+      }
+    },
+  },
+  mounted() {
+    this.$router.onReady(this.set404);
+    this.$router.afterEach((to, from) => {
+      this.set404();
+    });
+  },
+}
+
+export default error404Mixin;